/**
* React (with addons) v0.10.0 */
!function(e){if(“object”==typeof exports)module.exports=e();else if(“function”==typeof define&&define.amd)define(e);else{var f;“undefined”!=typeof window?f=window:“undefined”!=typeof global?f=global:“undefined”!=typeof self&&(f=self),f.React=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n){if(!t){var a=typeof require==“function”&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error(“Cannot find module '”o
“'”)}var f=n={exports:{}};t[0].call(f.exports,function(e){var n=t[1];return s(n?n:e)},f,f.exports,e,t,n,r)}return n.exports}var i=typeof require==“function”&&require;for(var o=0;o
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule AutoFocusMixin * @typechecks static-only */
“use strict”;
var focusNode = dereq(“./focusNode”);
var AutoFocusMixin = {
componentDidMount: function() { if (this.props.autoFocus) { focusNode(this.getDOMNode()); } }
};
module.exports = AutoFocusMixin;
},{“./focusNode”:113}],2:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule CSSCore * @typechecks */
var invariant = dereq(“./invariant”);
/**
* The CSSCore module specifies the API (and implements most of the methods) * that should be used when dealing with the display of elements (via their * CSS classes and visibility on screen. It is an API focused on mutating the * display and not reading it as no logical state should be encoded in the * display of elements. */
var CSSCore = {
/** * Adds the class passed in to the element if it doesn't already have it. * * @param {DOMElement} element the element to set the class on * @param {string} className the CSS className * @return {DOMElement} the element passed in */ addClass: function(element, className) { ("production" !== "development" ? invariant( !/\s/.test(className), 'CSSCore.addClass takes only a single class name. "%s" contains ' + 'multiple classes.', className ) : invariant(!/\s/.test(className))); if (className) { if (element.classList) { element.classList.add(className); } else if (!CSSCore.hasClass(element, className)) { element.className = element.className + ' ' + className; } } return element; }, /** * Removes the class passed in from the element * * @param {DOMElement} element the element to set the class on * @param {string} className the CSS className * @return {DOMElement} the element passed in */ removeClass: function(element, className) { ("production" !== "development" ? invariant( !/\s/.test(className), 'CSSCore.removeClass takes only a single class name. "%s" contains ' + 'multiple classes.', className ) : invariant(!/\s/.test(className))); if (className) { if (element.classList) { element.classList.remove(className); } else if (CSSCore.hasClass(element, className)) { element.className = element.className .replace(new RegExp('(^|\\s)' + className + '(?:\\s|$)', 'g'), '$1') .replace(/\s+/g, ' ') // multiple spaces to one .replace(/^\s*|\s*$/g, ''); // trim the ends } } return element; }, /** * Helper to add or remove a class from an element based on a condition. * * @param {DOMElement} element the element to set the class on * @param {string} className the CSS className * @param {*} bool condition to whether to add or remove the class * @return {DOMElement} the element passed in */ conditionClass: function(element, className, bool) { return (bool ? CSSCore.addClass : CSSCore.removeClass)(element, className); }, /** * Tests whether the element has the class specified. * * @param {DOMNode|DOMWindow} element the element to set the class on * @param {string} className the CSS className * @returns {boolean} true if the element has the class, false if not */ hasClass: function(element, className) { ("production" !== "development" ? invariant( !/\s/.test(className), 'CSS.hasClass takes only a single class name.' ) : invariant(!/\s/.test(className))); if (element.classList) { return !!className && element.classList.contains(className); } return (' ' + element.className + ' ').indexOf(' ' + className + ' ') > -1; }
};
module.exports = CSSCore;
},{“./invariant”:125}],3:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule CSSProperty */
“use strict”;
/**
* CSS properties which accept numbers but are not in units of "px". */
var isUnitlessNumber = {
columnCount: true, fillOpacity: true, flex: true, flexGrow: true, flexShrink: true, fontWeight: true, lineClamp: true, lineHeight: true, opacity: true, order: true, orphans: true, widows: true, zIndex: true, zoom: true
};
/**
* @param {string} prefix vendor-specific prefix, eg: Webkit * @param {string} key style name, eg: transitionDuration * @return {string} style name prefixed with `prefix`, properly camelCased, eg: * WebkitTransitionDuration */
function prefixKey(prefix, key) {
return prefix + key.charAt(0).toUpperCase() + key.substring(1);
}
/**
* Support style names that may come passed in prefixed by adding permutations * of vendor prefixes. */
var prefixes = ['Webkit', 'ms', 'Moz', 'O'];
// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an // infinite loop, because it iterates over the newly added props too. Object.keys(isUnitlessNumber).forEach(function(prop) {
prefixes.forEach(function(prefix) { isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop]; });
});
/**
* Most style properties can be unset by doing .style[prop] = '' but IE8 * doesn't like doing that with shorthand properties so for the properties that * IE8 breaks on, which are listed here, we instead unset each of the * individual properties. See http://bugs.jquery.com/ticket/12385. * The 4-value 'clock' properties like margin, padding, border-width seem to * behave without any problems. Curiously, list-style works too without any * special prodding. */
var shorthandPropertyExpansions = {
background: { backgroundImage: true, backgroundPosition: true, backgroundRepeat: true, backgroundColor: true }, border: { borderWidth: true, borderStyle: true, borderColor: true }, borderBottom: { borderBottomWidth: true, borderBottomStyle: true, borderBottomColor: true }, borderLeft: { borderLeftWidth: true, borderLeftStyle: true, borderLeftColor: true }, borderRight: { borderRightWidth: true, borderRightStyle: true, borderRightColor: true }, borderTop: { borderTopWidth: true, borderTopStyle: true, borderTopColor: true }, font: { fontStyle: true, fontVariant: true, fontWeight: true, fontSize: true, lineHeight: true, fontFamily: true }
};
var CSSProperty = {
isUnitlessNumber: isUnitlessNumber, shorthandPropertyExpansions: shorthandPropertyExpansions
};
module.exports = CSSProperty;
},{}],4:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule CSSPropertyOperations * @typechecks static-only */
“use strict”;
var CSSProperty = dereq(“./CSSProperty”);
var dangerousStyleValue = dereq(“./dangerousStyleValue”); var escapeTextForBrowser = dereq(“./escapeTextForBrowser”); var hyphenate = dereq(“./hyphenate”); var memoizeStringOnly = dereq(“./memoizeStringOnly”);
var processStyleName = memoizeStringOnly(function(styleName) {
return escapeTextForBrowser(hyphenate(styleName));
});
/**
* Operations for dealing with CSS properties. */
var CSSPropertyOperations = {
/** * Serializes a mapping of style properties for use as inline styles: * * > createMarkupForStyles({width: '200px', height: 0}) * "width:200px;height:0;" * * Undefined values are ignored so that declarative programming is easier. * * @param {object} styles * @return {?string} */ createMarkupForStyles: function(styles) { var serialized = ''; for (var styleName in styles) { if (!styles.hasOwnProperty(styleName)) { continue; } var styleValue = styles[styleName]; if (styleValue != null) { serialized += processStyleName(styleName) + ':'; serialized += dangerousStyleValue(styleName, styleValue) + ';'; } } return serialized || null; }, /** * Sets the value for multiple styles on a node. If a value is specified as * '' (empty string), the corresponding style property will be unset. * * @param {DOMElement} node * @param {object} styles */ setValueForStyles: function(node, styles) { var style = node.style; for (var styleName in styles) { if (!styles.hasOwnProperty(styleName)) { continue; } var styleValue = dangerousStyleValue(styleName, styles[styleName]); if (styleValue) { style[styleName] = styleValue; } else { var expansion = CSSProperty.shorthandPropertyExpansions[styleName]; if (expansion) { // Shorthand property that IE8 won't like unsetting, so unset each // component to placate it for (var individualStyleName in expansion) { style[individualStyleName] = ''; } } else { style[styleName] = ''; } } } }
};
module.exports = CSSPropertyOperations;
},{“./CSSProperty”:3,“./dangerousStyleValue”:108,“./escapeTextForBrowser”:111,“./hyphenate”:123,“./memoizeStringOnly”:133}],5:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ChangeEventPlugin */
“use strict”;
var EventConstants = dereq(“./EventConstants”); var EventPluginHub = dereq(“./EventPluginHub”); var EventPropagators = dereq(“./EventPropagators”); var ExecutionEnvironment = dereq(“./ExecutionEnvironment”); var ReactUpdates = dereq(“./ReactUpdates”); var SyntheticEvent = dereq(“./SyntheticEvent”);
var isEventSupported = dereq(“./isEventSupported”); var isTextInputElement = dereq(“./isTextInputElement”); var keyOf = dereq(“./keyOf”);
var topLevelTypes = EventConstants.topLevelTypes;
var eventTypes = {
change: { phasedRegistrationNames: { bubbled: keyOf({onChange: null}), captured: keyOf({onChangeCapture: null}) }, dependencies: [ topLevelTypes.topBlur, topLevelTypes.topChange, topLevelTypes.topClick, topLevelTypes.topFocus, topLevelTypes.topInput, topLevelTypes.topKeyDown, topLevelTypes.topKeyUp, topLevelTypes.topSelectionChange ] }
};
/**
* For IE shims */
var activeElement = null; var activeElementID = null; var activeElementValue = null; var activeElementValueProp = null;
/**
* SECTION: handle `change` event */
function shouldUseChangeEvent(elem) {
return ( elem.nodeName === 'SELECT' || (elem.nodeName === 'INPUT' && elem.type === 'file') );
}
var doesChangeEventBubble = false; if (ExecutionEnvironment.canUseDOM) {
// See `handleChange` comment below doesChangeEventBubble = isEventSupported('change') && ( !('documentMode' in document) || document.documentMode > 8 );
}
function manualDispatchChangeEvent(nativeEvent) {
var event = SyntheticEvent.getPooled( eventTypes.change, activeElementID, nativeEvent ); EventPropagators.accumulateTwoPhaseDispatches(event); // If change and propertychange bubbled, we'd just bind to it like all the // other events and have it go through ReactEventTopLevelCallback. Since it // doesn't, we manually listen for the events and so we have to enqueue and // process the abstract event manually. // // Batching is necessary here in order to ensure that all event handlers run // before the next rerender (including event handlers attached to ancestor // elements instead of directly on the input). Without this, controlled // components don't work properly in conjunction with event bubbling because // the component is rerendered and the value reverted before all the event // handlers can run. See https://github.com/facebook/react/issues/708. ReactUpdates.batchedUpdates(runEventInBatch, event);
}
function runEventInBatch(event) {
EventPluginHub.enqueueEvents(event); EventPluginHub.processEventQueue();
}
function startWatchingForChangeEventIE8(target, targetID) {
activeElement = target; activeElementID = targetID; activeElement.attachEvent('onchange', manualDispatchChangeEvent);
}
function stopWatchingForChangeEventIE8() {
if (!activeElement) { return; } activeElement.detachEvent('onchange', manualDispatchChangeEvent); activeElement = null; activeElementID = null;
}
function getTargetIDForChangeEvent(
topLevelType, topLevelTarget, topLevelTargetID) { if (topLevelType === topLevelTypes.topChange) { return topLevelTargetID; }
} function handleEventsForChangeEventIE8(
topLevelType, topLevelTarget, topLevelTargetID) { if (topLevelType === topLevelTypes.topFocus) { // stopWatching() should be a noop here but we call it just in case we // missed a blur event somehow. stopWatchingForChangeEventIE8(); startWatchingForChangeEventIE8(topLevelTarget, topLevelTargetID); } else if (topLevelType === topLevelTypes.topBlur) { stopWatchingForChangeEventIE8(); }
}
/**
* SECTION: handle `input` event */
var isInputEventSupported = false; if (ExecutionEnvironment.canUseDOM) {
// IE9 claims to support the input event but fails to trigger it when // deleting text, so we ignore its input events isInputEventSupported = isEventSupported('input') && ( !('documentMode' in document) || document.documentMode > 9 );
}
/**
* (For old IE.) Replacement getter/setter for the `value` property that gets * set on the active element. */
var newValueProp = {
get: function() { return activeElementValueProp.get.call(this); }, set: function(val) { // Cast to a string so we can do equality checks. activeElementValue = '' + val; activeElementValueProp.set.call(this, val); }
};
/**
* (For old IE.) Starts tracking propertychange events on the passed-in element * and override the value property so that we can distinguish user events from * value changes in JS. */
function startWatchingForValueChange(target, targetID) {
activeElement = target; activeElementID = targetID; activeElementValue = target.value; activeElementValueProp = Object.getOwnPropertyDescriptor( target.constructor.prototype, 'value' ); Object.defineProperty(activeElement, 'value', newValueProp); activeElement.attachEvent('onpropertychange', handlePropertyChange);
}
/**
* (For old IE.) Removes the event listeners from the currently-tracked element, * if any exists. */
function stopWatchingForValueChange() {
if (!activeElement) { return; } // delete restores the original property definition delete activeElement.value; activeElement.detachEvent('onpropertychange', handlePropertyChange); activeElement = null; activeElementID = null; activeElementValue = null; activeElementValueProp = null;
}
/**
* (For old IE.) Handles a propertychange event, sending a `change` event if * the value of the active element has changed. */
function handlePropertyChange(nativeEvent) {
if (nativeEvent.propertyName !== 'value') { return; } var value = nativeEvent.srcElement.value; if (value === activeElementValue) { return; } activeElementValue = value; manualDispatchChangeEvent(nativeEvent);
}
/**
* If a `change` event should be fired, returns the target's ID. */
function getTargetIDForInputEvent(
topLevelType, topLevelTarget, topLevelTargetID) { if (topLevelType === topLevelTypes.topInput) { // In modern browsers (i.e., not IE8 or IE9), the input event is exactly // what we want so fall through here and trigger an abstract event return topLevelTargetID; }
}
// For IE8 and IE9. function handleEventsForInputEventIE(
topLevelType, topLevelTarget, topLevelTargetID) { if (topLevelType === topLevelTypes.topFocus) { // In IE8, we can capture almost all .value changes by adding a // propertychange handler and looking for events with propertyName // equal to 'value' // In IE9, propertychange fires for most input events but is buggy and // doesn't fire when text is deleted, but conveniently, selectionchange // appears to fire in all of the remaining cases so we catch those and // forward the event if the value has changed // In either case, we don't want to call the event handler if the value // is changed from JS so we redefine a setter for `.value` that updates // our activeElementValue variable, allowing us to ignore those changes // // stopWatching() should be a noop here but we call it just in case we // missed a blur event somehow. stopWatchingForValueChange(); startWatchingForValueChange(topLevelTarget, topLevelTargetID); } else if (topLevelType === topLevelTypes.topBlur) { stopWatchingForValueChange(); }
}
// For IE8 and IE9. function getTargetIDForInputEventIE(
topLevelType, topLevelTarget, topLevelTargetID) { if (topLevelType === topLevelTypes.topSelectionChange || topLevelType === topLevelTypes.topKeyUp || topLevelType === topLevelTypes.topKeyDown) { // On the selectionchange event, the target is just document which isn't // helpful for us so just check activeElement instead. // // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire // propertychange on the first input event after setting `value` from a // script and fires only keydown, keypress, keyup. Catching keyup usually // gets it and catching keydown lets us fire an event for the first // keystroke if user does a key repeat (it'll be a little delayed: right // before the second keystroke). Other input methods (e.g., paste) seem to // fire selectionchange normally. if (activeElement && activeElement.value !== activeElementValue) { activeElementValue = activeElement.value; return activeElementID; } }
}
/**
* SECTION: handle `click` event */
function shouldUseClickEvent(elem) {
// Use the `click` event to detect changes to checkbox and radio inputs. // This approach works across all browsers, whereas `change` does not fire // until `blur` in IE8. return ( elem.nodeName === 'INPUT' && (elem.type === 'checkbox' || elem.type === 'radio') );
}
function getTargetIDForClickEvent(
topLevelType, topLevelTarget, topLevelTargetID) { if (topLevelType === topLevelTypes.topClick) { return topLevelTargetID; }
}
/**
* This plugin creates an `onChange` event that normalizes change events * across form elements. This event fires at a time when it's possible to * change the element's value without seeing a flicker. * * Supported elements are: * - input (see `isTextInputElement`) * - textarea * - select */
var ChangeEventPlugin = {
eventTypes: eventTypes, /** * @param {string} topLevelType Record from `EventConstants`. * @param {DOMEventTarget} topLevelTarget The listening component root node. * @param {string} topLevelTargetID ID of `topLevelTarget`. * @param {object} nativeEvent Native browser event. * @return {*} An accumulation of synthetic events. * @see {EventPluginHub.extractEvents} */ extractEvents: function( topLevelType, topLevelTarget, topLevelTargetID, nativeEvent) { var getTargetIDFunc, handleEventFunc; if (shouldUseChangeEvent(topLevelTarget)) { if (doesChangeEventBubble) { getTargetIDFunc = getTargetIDForChangeEvent; } else { handleEventFunc = handleEventsForChangeEventIE8; } } else if (isTextInputElement(topLevelTarget)) { if (isInputEventSupported) { getTargetIDFunc = getTargetIDForInputEvent; } else { getTargetIDFunc = getTargetIDForInputEventIE; handleEventFunc = handleEventsForInputEventIE; } } else if (shouldUseClickEvent(topLevelTarget)) { getTargetIDFunc = getTargetIDForClickEvent; } if (getTargetIDFunc) { var targetID = getTargetIDFunc( topLevelType, topLevelTarget, topLevelTargetID ); if (targetID) { var event = SyntheticEvent.getPooled( eventTypes.change, targetID, nativeEvent ); EventPropagators.accumulateTwoPhaseDispatches(event); return event; } } if (handleEventFunc) { handleEventFunc( topLevelType, topLevelTarget, topLevelTargetID ); } }
};
module.exports = ChangeEventPlugin;
},{“./EventConstants”:15,“./EventPluginHub”:17,“./EventPropagators”:20,“./ExecutionEnvironment”:21,“./ReactUpdates”:81,“./SyntheticEvent”:89,“./isEventSupported”:126,“./isTextInputElement”:128,“./keyOf”:132}],6:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ClientReactRootIndex * @typechecks */
“use strict”;
var nextReactRootIndex = 0;
var ClientReactRootIndex = {
createReactRootIndex: function() { return nextReactRootIndex++; }
};
module.exports = ClientReactRootIndex;
},{}],7:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule CompositionEventPlugin * @typechecks static-only */
“use strict”;
var EventConstants = dereq(“./EventConstants”); var EventPropagators = dereq(“./EventPropagators”); var ExecutionEnvironment = dereq(“./ExecutionEnvironment”); var ReactInputSelection = dereq(“./ReactInputSelection”); var SyntheticCompositionEvent = dereq(“./SyntheticCompositionEvent”);
var getTextContentAccessor = dereq(“./getTextContentAccessor”); var keyOf = dereq(“./keyOf”);
var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space var START_KEYCODE = 229;
var useCompositionEvent = (
ExecutionEnvironment.canUseDOM && 'CompositionEvent' in window
);
// In IE9+, we have access to composition events, but the data supplied // by the native compositionend event may be incorrect. In Korean, for example, // the compositionend event contains only one character regardless of // how many characters have been composed since compositionstart. // We therefore use the fallback data while still using the native // events as triggers. var useFallbackData = (
!useCompositionEvent || 'documentMode' in document && document.documentMode > 8
);
var topLevelTypes = EventConstants.topLevelTypes; var currentComposition = null;
// Events and their corresponding property names. var eventTypes = {
compositionEnd: { phasedRegistrationNames: { bubbled: keyOf({onCompositionEnd: null}), captured: keyOf({onCompositionEndCapture: null}) }, dependencies: [ topLevelTypes.topBlur, topLevelTypes.topCompositionEnd, topLevelTypes.topKeyDown, topLevelTypes.topKeyPress, topLevelTypes.topKeyUp, topLevelTypes.topMouseDown ] }, compositionStart: { phasedRegistrationNames: { bubbled: keyOf({onCompositionStart: null}), captured: keyOf({onCompositionStartCapture: null}) }, dependencies: [ topLevelTypes.topBlur, topLevelTypes.topCompositionStart, topLevelTypes.topKeyDown, topLevelTypes.topKeyPress, topLevelTypes.topKeyUp, topLevelTypes.topMouseDown ] }, compositionUpdate: { phasedRegistrationNames: { bubbled: keyOf({onCompositionUpdate: null}), captured: keyOf({onCompositionUpdateCapture: null}) }, dependencies: [ topLevelTypes.topBlur, topLevelTypes.topCompositionUpdate, topLevelTypes.topKeyDown, topLevelTypes.topKeyPress, topLevelTypes.topKeyUp, topLevelTypes.topMouseDown ] }
};
/**
* Translate native top level events into event types. * * @param {string} topLevelType * @return {object} */
function getCompositionEventType(topLevelType) {
switch (topLevelType) { case topLevelTypes.topCompositionStart: return eventTypes.compositionStart; case topLevelTypes.topCompositionEnd: return eventTypes.compositionEnd; case topLevelTypes.topCompositionUpdate: return eventTypes.compositionUpdate; }
}
/**
* Does our fallback best-guess model think this event signifies that * composition has begun? * * @param {string} topLevelType * @param {object} nativeEvent * @return {boolean} */
function isFallbackStart(topLevelType, nativeEvent) {
return ( topLevelType === topLevelTypes.topKeyDown && nativeEvent.keyCode === START_KEYCODE );
}
/**
* Does our fallback mode think that this event is the end of composition? * * @param {string} topLevelType * @param {object} nativeEvent * @return {boolean} */
function isFallbackEnd(topLevelType, nativeEvent) {
switch (topLevelType) { case topLevelTypes.topKeyUp: // Command keys insert or clear IME input. return (END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1); case topLevelTypes.topKeyDown: // Expect IME keyCode on each keydown. If we get any other // code we must have exited earlier. return (nativeEvent.keyCode !== START_KEYCODE); case topLevelTypes.topKeyPress: case topLevelTypes.topMouseDown: case topLevelTypes.topBlur: // Events are not possible without cancelling IME. return true; default: return false; }
}
/**
* Helper class stores information about selection and document state * so we can figure out what changed at a later date. * * @param {DOMEventTarget} root */
function FallbackCompositionState(root) {
this.root = root; this.startSelection = ReactInputSelection.getSelection(root); this.startValue = this.getText();
}
/**
* Get current text of input. * * @return {string} */
FallbackCompositionState.prototype.getText = function() {
return this.root.value || this.root[getTextContentAccessor()];
};
/**
* Text that has changed since the start of composition. * * @return {string} */
FallbackCompositionState.prototype.getData = function() {
var endValue = this.getText(); var prefixLength = this.startSelection.start; var suffixLength = this.startValue.length - this.startSelection.end; return endValue.substr( prefixLength, endValue.length - suffixLength - prefixLength );
};
/**
* This plugin creates `onCompositionStart`, `onCompositionUpdate` and * `onCompositionEnd` events on inputs, textareas and contentEditable * nodes. */
var CompositionEventPlugin = {
eventTypes: eventTypes, /** * @param {string} topLevelType Record from `EventConstants`. * @param {DOMEventTarget} topLevelTarget The listening component root node. * @param {string} topLevelTargetID ID of `topLevelTarget`. * @param {object} nativeEvent Native browser event. * @return {*} An accumulation of synthetic events. * @see {EventPluginHub.extractEvents} */ extractEvents: function( topLevelType, topLevelTarget, topLevelTargetID, nativeEvent) { var eventType; var data; if (useCompositionEvent) { eventType = getCompositionEventType(topLevelType); } else if (!currentComposition) { if (isFallbackStart(topLevelType, nativeEvent)) { eventType = eventTypes.compositionStart; } } else if (isFallbackEnd(topLevelType, nativeEvent)) { eventType = eventTypes.compositionEnd; } if (useFallbackData) { // The current composition is stored statically and must not be // overwritten while composition continues. if (!currentComposition && eventType === eventTypes.compositionStart) { currentComposition = new FallbackCompositionState(topLevelTarget); } else if (eventType === eventTypes.compositionEnd) { if (currentComposition) { data = currentComposition.getData(); currentComposition = null; } } } if (eventType) { var event = SyntheticCompositionEvent.getPooled( eventType, topLevelTargetID, nativeEvent ); if (data) { // Inject data generated from fallback path into the synthetic event. // This matches the property of native CompositionEventInterface. event.data = data; } EventPropagators.accumulateTwoPhaseDispatches(event); return event; } }
};
module.exports = CompositionEventPlugin;
},{“./EventConstants”:15,“./EventPropagators”:20,“./ExecutionEnvironment”:21,“./ReactInputSelection”:56,“./SyntheticCompositionEvent”:87,“./getTextContentAccessor”:121,“./keyOf”:132}],8:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule DOMChildrenOperations * @typechecks static-only */
“use strict”;
var Danger = dereq(“./Danger”); var ReactMultiChildUpdateTypes = dereq(“./ReactMultiChildUpdateTypes”);
var getTextContentAccessor = dereq(“./getTextContentAccessor”);
/**
* The DOM property to use when setting text content. * * @type {string} * @private */
var textContentAccessor = getTextContentAccessor();
/**
* Inserts `childNode` as a child of `parentNode` at the `index`. * * @param {DOMElement} parentNode Parent node in which to insert. * @param {DOMElement} childNode Child node to insert. * @param {number} index Index at which to insert the child. * @internal */
function insertChildAt(parentNode, childNode, index) {
var childNodes = parentNode.childNodes; if (childNodes[index] === childNode) { return; } // If `childNode` is already a child of `parentNode`, remove it so that // computing `childNodes[index]` takes into account the removal. if (childNode.parentNode === parentNode) { parentNode.removeChild(childNode); } if (index >= childNodes.length) { parentNode.appendChild(childNode); } else { parentNode.insertBefore(childNode, childNodes[index]); }
}
var updateTextContent; if (textContentAccessor === 'textContent') {
/** * Sets the text content of `node` to `text`. * * @param {DOMElement} node Node to change * @param {string} text New text content */ updateTextContent = function(node, text) { node.textContent = text; };
} else {
/** * Sets the text content of `node` to `text`. * * @param {DOMElement} node Node to change * @param {string} text New text content */ updateTextContent = function(node, text) { // In order to preserve newlines correctly, we can't use .innerText to set // the contents (see #1080), so we empty the element then append a text node while (node.firstChild) { node.removeChild(node.firstChild); } if (text) { var doc = node.ownerDocument || document; node.appendChild(doc.createTextNode(text)); } };
}
/**
* Operations for updating with DOM children. */
var DOMChildrenOperations = {
dangerouslyReplaceNodeWithMarkup: Danger.dangerouslyReplaceNodeWithMarkup, updateTextContent: updateTextContent, /** * Updates a component's children by processing a series of updates. The * update configurations are each expected to have a `parentNode` property. * * @param {array<object>} updates List of update configurations. * @param {array<string>} markupList List of markup strings. * @internal */ processUpdates: function(updates, markupList) { var update; // Mapping from parent IDs to initial child orderings. var initialChildren = null; // List of children that will be moved or removed. var updatedChildren = null; for (var i = 0; update = updates[i]; i++) { if (update.type === ReactMultiChildUpdateTypes.MOVE_EXISTING || update.type === ReactMultiChildUpdateTypes.REMOVE_NODE) { var updatedIndex = update.fromIndex; var updatedChild = update.parentNode.childNodes[updatedIndex]; var parentID = update.parentID; initialChildren = initialChildren || {}; initialChildren[parentID] = initialChildren[parentID] || []; initialChildren[parentID][updatedIndex] = updatedChild; updatedChildren = updatedChildren || []; updatedChildren.push(updatedChild); } } var renderedMarkup = Danger.dangerouslyRenderMarkup(markupList); // Remove updated children first so that `toIndex` is consistent. if (updatedChildren) { for (var j = 0; j < updatedChildren.length; j++) { updatedChildren[j].parentNode.removeChild(updatedChildren[j]); } } for (var k = 0; update = updates[k]; k++) { switch (update.type) { case ReactMultiChildUpdateTypes.INSERT_MARKUP: insertChildAt( update.parentNode, renderedMarkup[update.markupIndex], update.toIndex ); break; case ReactMultiChildUpdateTypes.MOVE_EXISTING: insertChildAt( update.parentNode, initialChildren[update.parentID][update.fromIndex], update.toIndex ); break; case ReactMultiChildUpdateTypes.TEXT_CONTENT: updateTextContent( update.parentNode, update.textContent ); break; case ReactMultiChildUpdateTypes.REMOVE_NODE: // Already removed by the for-loop above. break; } } }
};
module.exports = DOMChildrenOperations;
},{“./Danger”:11,“./ReactMultiChildUpdateTypes”:63,“./getTextContentAccessor”:121}],9:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule DOMProperty * @typechecks static-only */
/*jslint bitwise: true */
“use strict”;
var invariant = dereq(“./invariant”);
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_POSITIVE_NUMERIC_VALUE: 0x10, /** * Inject some specialized knowledge about the DOM. This takes a config object * with the following properties: * * isCustomAttribute: function that given an attribute name will return true * if it can be inserted into the DOM verbatim. Useful for data-* or aria-* * attributes where it's impossible to enumerate all of the possible * attribute names, * * Properties: object mapping DOM property name to one of the * DOMPropertyInjection constants or null. If your attribute isn't in here, * it won't get written to the DOM. * * DOMAttributeNames: object mapping React attribute name to the DOM * attribute name. Attribute names not specified use the **lowercase** * normalized name. * * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties. * Property names not specified use the normalized name. * * DOMMutationMethods: Properties that require special mutation methods. If * `value` is undefined, the mutation method should unset the property. * * @param {object} domPropertyConfig the config as described above. */ injectDOMPropertyConfig: function(domPropertyConfig) { var Properties = domPropertyConfig.Properties || {}; var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {}; var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {}; var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {}; if (domPropertyConfig.isCustomAttribute) { DOMProperty._isCustomAttributeFunctions.push( domPropertyConfig.isCustomAttribute ); } for (var propName in Properties) { ("production" !== "development" ? invariant( !DOMProperty.isStandardName[propName], 'injectDOMPropertyConfig(...): You\'re trying to inject DOM property ' + '\'%s\' which has already been injected. You may be accidentally ' + 'injecting the same DOM property config twice, or you may be ' + 'injecting two configs that have conflicting property names.', propName ) : invariant(!DOMProperty.isStandardName[propName])); DOMProperty.isStandardName[propName] = true; var lowerCased = propName.toLowerCase(); DOMProperty.getPossibleStandardName[lowerCased] = propName; var attributeName = DOMAttributeNames[propName]; if (attributeName) { DOMProperty.getPossibleStandardName[attributeName] = propName; } DOMProperty.getAttributeName[propName] = attributeName || lowerCased; DOMProperty.getPropertyName[propName] = DOMPropertyNames[propName] || propName; var mutationMethod = DOMMutationMethods[propName]; if (mutationMethod) { DOMProperty.getMutationMethod[propName] = mutationMethod; } var propConfig = Properties[propName]; DOMProperty.mustUseAttribute[propName] = propConfig & DOMPropertyInjection.MUST_USE_ATTRIBUTE; DOMProperty.mustUseProperty[propName] = propConfig & DOMPropertyInjection.MUST_USE_PROPERTY; DOMProperty.hasSideEffects[propName] = propConfig & DOMPropertyInjection.HAS_SIDE_EFFECTS; DOMProperty.hasBooleanValue[propName] = propConfig & DOMPropertyInjection.HAS_BOOLEAN_VALUE; DOMProperty.hasPositiveNumericValue[propName] = propConfig & DOMPropertyInjection.HAS_POSITIVE_NUMERIC_VALUE; ("production" !== "development" ? invariant( !DOMProperty.mustUseAttribute[propName] || !DOMProperty.mustUseProperty[propName], 'DOMProperty: Cannot require using both attribute and property: %s', propName ) : invariant(!DOMProperty.mustUseAttribute[propName] || !DOMProperty.mustUseProperty[propName])); ("production" !== "development" ? invariant( DOMProperty.mustUseProperty[propName] || !DOMProperty.hasSideEffects[propName], 'DOMProperty: Properties that have side effects must use property: %s', propName ) : invariant(DOMProperty.mustUseProperty[propName] || !DOMProperty.hasSideEffects[propName])); ("production" !== "development" ? invariant( !DOMProperty.hasBooleanValue[propName] || !DOMProperty.hasPositiveNumericValue[propName], 'DOMProperty: Cannot have both boolean and positive numeric value: %s', propName ) : invariant(!DOMProperty.hasBooleanValue[propName] || !DOMProperty.hasPositiveNumericValue[propName])); } }
}; var defaultValueCache = {};
/**
* DOMProperty exports lookup objects that can be used like functions: * * > DOMProperty.isValid['id'] * true * > DOMProperty.isValid['foobar'] * undefined * * Although this may be confusing, it performs better in general. * * @see http://jsperf.com/key-exists * @see http://jsperf.com/key-missing */
var DOMProperty = {
ID_ATTRIBUTE_NAME: 'data-reactid', /** * Checks whether a property name is a standard property. * @type {Object} */ isStandardName: {}, /** * Mapping from lowercase property names to the properly cased version, used * to warn in the case of missing properties. * @type {Object} */ getPossibleStandardName: {}, /** * Mapping from normalized names to attribute names that differ. Attribute * names are used when rendering markup or with `*Attribute()`. * @type {Object} */ getAttributeName: {}, /** * Mapping from normalized names to properties on DOM node instances. * (This includes properties that mutate due to external factors.) * @type {Object} */ getPropertyName: {}, /** * Mapping from normalized names to mutation methods. This will only exist if * mutation cannot be set simply by the property or `setAttribute()`. * @type {Object} */ getMutationMethod: {}, /** * Whether the property must be accessed and mutated as an object property. * @type {Object} */ mustUseAttribute: {}, /** * Whether the property must be accessed and mutated using `*Attribute()`. * (This includes anything that fails `<propName> in <element>`.) * @type {Object} */ mustUseProperty: {}, /** * Whether or not setting a value causes side effects such as triggering * resources to be loaded or text selection changes. We must ensure that * the value is only set if it has changed. * @type {Object} */ hasSideEffects: {}, /** * Whether the property should be removed when set to a falsey value. * @type {Object} */ hasBooleanValue: {}, /** * Whether the property must be positive numeric or parse as a positive * numeric and should be removed when set to a falsey value. * @type {Object} */ hasPositiveNumericValue: {}, /** * All of the isCustomAttribute() functions that have been injected. */ _isCustomAttributeFunctions: [], /** * Checks whether a property name is a custom attribute. * @method */ isCustomAttribute: function(attributeName) { for (var i = 0; i < DOMProperty._isCustomAttributeFunctions.length; i++) { var isCustomAttributeFn = DOMProperty._isCustomAttributeFunctions[i]; if (isCustomAttributeFn(attributeName)) { return true; } } return false; }, /** * Returns the default property value for a DOM property (i.e., not an * attribute). Most default values are '' or false, but not all. Worse yet, * some (in particular, `type`) vary depending on the type of element. * * TODO: Is it better to grab all the possible properties when creating an * element to avoid having to create the same element twice? */ getDefaultValueForProperty: function(nodeName, prop) { var nodeDefaults = defaultValueCache[nodeName]; var testElement; if (!nodeDefaults) { defaultValueCache[nodeName] = nodeDefaults = {}; } if (!(prop in nodeDefaults)) { testElement = document.createElement(nodeName); nodeDefaults[prop] = testElement[prop]; } return nodeDefaults[prop]; }, injection: DOMPropertyInjection
};
module.exports = DOMProperty;
},{“./invariant”:125}],10:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule DOMPropertyOperations * @typechecks static-only */
“use strict”;
var DOMProperty = dereq(“./DOMProperty”);
var escapeTextForBrowser = dereq(“./escapeTextForBrowser”); var memoizeStringOnly = dereq(“./memoizeStringOnly”); var warning = dereq(“./warning”);
function shouldIgnoreValue(name, value) {
return value == null || DOMProperty.hasBooleanValue[name] && !value || DOMProperty.hasPositiveNumericValue[name] && (isNaN(value) || value < 1);
}
var processAttributeNameAndPrefix = memoizeStringOnly(function(name) {
return escapeTextForBrowser(name) + '="';
});
if (“production” !== “development”) {
var reactProps = { children: true, dangerouslySetInnerHTML: true, key: true, ref: true }; var warnedProperties = {}; var warnUnknownProperty = function(name) { if (reactProps[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[lowerCasedName]; // For now, only warn when we have a suggested correction. This prevents // logging too much when using transferPropsTo. ("production" !== "development" ? warning( standardName == null, 'Unknown DOM property ' + name + '. Did you mean ' + standardName + '?' ) : null); };
}
/**
* Operations for dealing with DOM properties. */
var DOMPropertyOperations = {
/** * Creates markup for the ID property. * * @param {string} id Unescaped ID. * @return {string} Markup string. */ createMarkupForID: function(id) { return processAttributeNameAndPrefix(DOMProperty.ID_ATTRIBUTE_NAME) + escapeTextForBrowser(id) + '"'; }, /** * Creates markup for a property. * * @param {string} name * @param {*} value * @return {?string} Markup string, or null if the property was invalid. */ createMarkupForProperty: function(name, value) { if (DOMProperty.isStandardName[name]) { if (shouldIgnoreValue(name, value)) { return ''; } var attributeName = DOMProperty.getAttributeName[name]; if (DOMProperty.hasBooleanValue[name]) { return escapeTextForBrowser(attributeName); } return processAttributeNameAndPrefix(attributeName) + escapeTextForBrowser(value) + '"'; } else if (DOMProperty.isCustomAttribute(name)) { if (value == null) { return ''; } return processAttributeNameAndPrefix(name) + escapeTextForBrowser(value) + '"'; } else if ("production" !== "development") { warnUnknownProperty(name); } return null; }, /** * Sets the value for a property on a node. * * @param {DOMElement} node * @param {string} name * @param {*} value */ setValueForProperty: function(node, name, value) { if (DOMProperty.isStandardName[name]) { var mutationMethod = DOMProperty.getMutationMethod[name]; if (mutationMethod) { mutationMethod(node, value); } else if (shouldIgnoreValue(name, value)) { this.deleteValueForProperty(node, name); } else if (DOMProperty.mustUseAttribute[name]) { node.setAttribute(DOMProperty.getAttributeName[name], '' + value); } else { var propName = DOMProperty.getPropertyName[name]; if (!DOMProperty.hasSideEffects[name] || node[propName] !== value) { node[propName] = value; } } } else if (DOMProperty.isCustomAttribute(name)) { if (value == null) { node.removeAttribute(DOMProperty.getAttributeName[name]); } else { node.setAttribute(name, '' + value); } } else if ("production" !== "development") { warnUnknownProperty(name); } }, /** * Deletes the value for a property on a node. * * @param {DOMElement} node * @param {string} name */ deleteValueForProperty: function(node, name) { if (DOMProperty.isStandardName[name]) { var mutationMethod = DOMProperty.getMutationMethod[name]; if (mutationMethod) { mutationMethod(node, undefined); } else if (DOMProperty.mustUseAttribute[name]) { node.removeAttribute(DOMProperty.getAttributeName[name]); } else { var propName = DOMProperty.getPropertyName[name]; var defaultValue = DOMProperty.getDefaultValueForProperty( node.nodeName, propName ); if (!DOMProperty.hasSideEffects[name] || node[propName] !== defaultValue) { node[propName] = defaultValue; } } } else if (DOMProperty.isCustomAttribute(name)) { node.removeAttribute(name); } else if ("production" !== "development") { warnUnknownProperty(name); } }
};
module.exports = DOMPropertyOperations;
},{“./DOMProperty”:9,“./escapeTextForBrowser”:111,“./memoizeStringOnly”:133,“./warning”:148}],11:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule Danger * @typechecks static-only */
/*jslint evil: true, sub: true */
“use strict”;
var ExecutionEnvironment = dereq(“./ExecutionEnvironment”);
var createNodesFromMarkup = dereq(“./createNodesFromMarkup”); var emptyFunction = dereq(“./emptyFunction”); var getMarkupWrap = dereq(“./getMarkupWrap”); var invariant = dereq(“./invariant”);
var OPEN_TAG_NAME_EXP = /^(<[^ />]+)/; var RESULT_INDEX_ATTR = 'data-danger-index';
/**
* Extracts the `nodeName` from a string of markup. * * NOTE: Extracting the `nodeName` does not require a regular expression match * because we make assumptions about React-generated markup (i.e. there are no * spaces surrounding the opening tag and there is at least one attribute). * * @param {string} markup String of markup. * @return {string} Node name of the supplied markup. * @see http://jsperf.com/extract-nodename */
function getNodeName(markup) {
return markup.substring(1, markup.indexOf(' '));
}
var Danger = {
/** * Renders markup into an array of nodes. The markup is expected to render * into a list of root nodes. Also, the length of `resultList` and * `markupList` should be the same. * * @param {array<string>} markupList List of markup strings to render. * @return {array<DOMElement>} List of rendered nodes. * @internal */ dangerouslyRenderMarkup: function(markupList) { ("production" !== "development" ? invariant( ExecutionEnvironment.canUseDOM, 'dangerouslyRenderMarkup(...): Cannot render markup in a Worker ' + 'thread. This is likely a bug in the framework. Please report ' + 'immediately.' ) : invariant(ExecutionEnvironment.canUseDOM)); var nodeName; var markupByNodeName = {}; // Group markup by `nodeName` if a wrap is necessary, else by '*'. for (var i = 0; i < markupList.length; i++) { ("production" !== "development" ? invariant( markupList[i], 'dangerouslyRenderMarkup(...): Missing markup.' ) : invariant(markupList[i])); nodeName = getNodeName(markupList[i]); nodeName = getMarkupWrap(nodeName) ? nodeName : '*'; markupByNodeName[nodeName] = markupByNodeName[nodeName] || []; markupByNodeName[nodeName][i] = markupList[i]; } var resultList = []; var resultListAssignmentCount = 0; for (nodeName in markupByNodeName) { if (!markupByNodeName.hasOwnProperty(nodeName)) { continue; } var markupListByNodeName = markupByNodeName[nodeName]; // This for-in loop skips the holes of the sparse array. The order of // iteration should follow the order of assignment, which happens to match // numerical index order, but we don't rely on that. for (var resultIndex in markupListByNodeName) { if (markupListByNodeName.hasOwnProperty(resultIndex)) { var markup = markupListByNodeName[resultIndex]; // Push the requested markup with an additional RESULT_INDEX_ATTR // attribute. If the markup does not start with a < character, it // will be discarded below (with an appropriate console.error). markupListByNodeName[resultIndex] = markup.replace( OPEN_TAG_NAME_EXP, // This index will be parsed back out below. '$1 ' + RESULT_INDEX_ATTR + '="' + resultIndex + '" ' ); } } // Render each group of markup with similar wrapping `nodeName`. var renderNodes = createNodesFromMarkup( markupListByNodeName.join(''), emptyFunction // Do nothing special with <script> tags. ); for (i = 0; i < renderNodes.length; ++i) { var renderNode = renderNodes[i]; if (renderNode.hasAttribute && renderNode.hasAttribute(RESULT_INDEX_ATTR)) { resultIndex = +renderNode.getAttribute(RESULT_INDEX_ATTR); renderNode.removeAttribute(RESULT_INDEX_ATTR); ("production" !== "development" ? invariant( !resultList.hasOwnProperty(resultIndex), 'Danger: Assigning to an already-occupied result index.' ) : invariant(!resultList.hasOwnProperty(resultIndex))); resultList[resultIndex] = renderNode; // This should match resultList.length and markupList.length when // we're done. resultListAssignmentCount += 1; } else if ("production" !== "development") { console.error( "Danger: Discarding unexpected node:", renderNode ); } } } // Although resultList was populated out of order, it should now be a dense // array. ("production" !== "development" ? invariant( resultListAssignmentCount === resultList.length, 'Danger: Did not assign to every index of resultList.' ) : invariant(resultListAssignmentCount === resultList.length)); ("production" !== "development" ? invariant( resultList.length === markupList.length, 'Danger: Expected markup to render %s nodes, but rendered %s.', markupList.length, resultList.length ) : invariant(resultList.length === markupList.length)); return resultList; }, /** * Replaces a node with a string of markup at its current position within its * parent. The markup must render into a single root node. * * @param {DOMElement} oldChild Child node to replace. * @param {string} markup Markup to render in place of the child node. * @internal */ dangerouslyReplaceNodeWithMarkup: function(oldChild, markup) { ("production" !== "development" ? invariant( ExecutionEnvironment.canUseDOM, 'dangerouslyReplaceNodeWithMarkup(...): Cannot render markup in a ' + 'worker thread. This is likely a bug in the framework. Please report ' + 'immediately.' ) : invariant(ExecutionEnvironment.canUseDOM)); ("production" !== "development" ? invariant(markup, 'dangerouslyReplaceNodeWithMarkup(...): Missing markup.') : invariant(markup)); ("production" !== "development" ? invariant( oldChild.tagName.toLowerCase() !== 'html', 'dangerouslyReplaceNodeWithMarkup(...): Cannot replace markup of the ' + '<html> 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 renderComponentToString().' ) : invariant(oldChild.tagName.toLowerCase() !== 'html')); var newChild = createNodesFromMarkup(markup, emptyFunction)[0]; oldChild.parentNode.replaceChild(newChild, oldChild); }
};
module.exports = Danger;
},{“./ExecutionEnvironment”:21,“./createNodesFromMarkup”:105,“./emptyFunction”:109,“./getMarkupWrap”:118,“./invariant”:125}],12:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule DefaultDOMPropertyConfig */
/*jslint bitwise: true*/
“use strict”;
var DOMProperty = dereq(“./DOMProperty”);
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; var HAS_POSITIVE_NUMERIC_VALUE =
DOMProperty.injection.HAS_POSITIVE_NUMERIC_VALUE;
var DefaultDOMPropertyConfig = {
isCustomAttribute: RegExp.prototype.test.bind( /^(data|aria)-[a-z_][a-z\d_.\-]*$/ ), Properties: { /** * Standard Properties */ accept: null, accessKey: null, action: null, allowFullScreen: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE, allowTransparency: MUST_USE_ATTRIBUTE, alt: null, async: HAS_BOOLEAN_VALUE, autoComplete: null, // autoFocus is polyfilled/normalized by AutoFocusMixin // autoFocus: HAS_BOOLEAN_VALUE, autoPlay: HAS_BOOLEAN_VALUE, cellPadding: null, cellSpacing: null, charSet: MUST_USE_ATTRIBUTE, checked: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, className: 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, crossOrigin: null, data: null, // For `<object />` acts as `src`. dateTime: MUST_USE_ATTRIBUTE, defer: HAS_BOOLEAN_VALUE, dir: null, disabled: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE, download: null, draggable: null, encType: null, form: MUST_USE_ATTRIBUTE, formNoValidate: HAS_BOOLEAN_VALUE, frameBorder: MUST_USE_ATTRIBUTE, height: MUST_USE_ATTRIBUTE, hidden: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE, href: null, hrefLang: null, htmlFor: null, httpEquiv: null, icon: null, id: MUST_USE_PROPERTY, label: null, lang: null, list: null, loop: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, max: null, maxLength: MUST_USE_ATTRIBUTE, mediaGroup: null, method: null, min: null, multiple: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, muted: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, name: null, noValidate: HAS_BOOLEAN_VALUE, pattern: null, placeholder: null, poster: null, preload: null, radioGroup: null, readOnly: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, rel: null, required: HAS_BOOLEAN_VALUE, role: MUST_USE_ATTRIBUTE, rows: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE, rowSpan: null, sandbox: null, scope: null, scrollLeft: MUST_USE_PROPERTY, scrollTop: MUST_USE_PROPERTY, seamless: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE, selected: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, size: MUST_USE_ATTRIBUTE | HAS_POSITIVE_NUMERIC_VALUE, span: HAS_POSITIVE_NUMERIC_VALUE, spellCheck: null, src: null, srcDoc: MUST_USE_PROPERTY, srcSet: null, step: null, style: null, tabIndex: null, target: null, title: null, type: null, value: MUST_USE_PROPERTY | HAS_SIDE_EFFECTS, width: MUST_USE_ATTRIBUTE, wmode: MUST_USE_ATTRIBUTE, /** * Non-standard Properties */ autoCapitalize: null, // Supported in Mobile Safari for keyboard hints autoCorrect: null, // Supported in Mobile Safari for keyboard hints property: null, // Supports OG in meta tags /** * SVG Properties */ cx: MUST_USE_ATTRIBUTE, cy: MUST_USE_ATTRIBUTE, d: MUST_USE_ATTRIBUTE, fill: MUST_USE_ATTRIBUTE, fx: MUST_USE_ATTRIBUTE, fy: MUST_USE_ATTRIBUTE, gradientTransform: MUST_USE_ATTRIBUTE, gradientUnits: MUST_USE_ATTRIBUTE, offset: MUST_USE_ATTRIBUTE, points: MUST_USE_ATTRIBUTE, r: MUST_USE_ATTRIBUTE, rx: MUST_USE_ATTRIBUTE, ry: MUST_USE_ATTRIBUTE, spreadMethod: MUST_USE_ATTRIBUTE, stopColor: MUST_USE_ATTRIBUTE, stopOpacity: MUST_USE_ATTRIBUTE, stroke: MUST_USE_ATTRIBUTE, strokeLinecap: MUST_USE_ATTRIBUTE, strokeWidth: MUST_USE_ATTRIBUTE, textAnchor: MUST_USE_ATTRIBUTE, transform: MUST_USE_ATTRIBUTE, version: MUST_USE_ATTRIBUTE, viewBox: MUST_USE_ATTRIBUTE, x1: MUST_USE_ATTRIBUTE, x2: MUST_USE_ATTRIBUTE, x: MUST_USE_ATTRIBUTE, y1: MUST_USE_ATTRIBUTE, y2: MUST_USE_ATTRIBUTE, y: MUST_USE_ATTRIBUTE }, DOMAttributeNames: { className: 'class', gradientTransform: 'gradientTransform', gradientUnits: 'gradientUnits', htmlFor: 'for', spreadMethod: 'spreadMethod', stopColor: 'stop-color', stopOpacity: 'stop-opacity', strokeLinecap: 'stroke-linecap', strokeWidth: 'stroke-width', textAnchor: 'text-anchor', viewBox: 'viewBox' }, DOMPropertyNames: { autoCapitalize: 'autocapitalize', autoComplete: 'autocomplete', autoCorrect: 'autocorrect', autoFocus: 'autofocus', autoPlay: 'autoplay', encType: 'enctype', hrefLang: 'hreflang', radioGroup: 'radiogroup', spellCheck: 'spellcheck', srcDoc: 'srcdoc', srcSet: 'srcset' }
};
module.exports = DefaultDOMPropertyConfig;
},{“./DOMProperty”:9}],13:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule DefaultEventPluginOrder */
“use strict”;
var keyOf = _dereq_("./keyOf");
/**
* Module that is injectable into `EventPluginHub`, that specifies a * deterministic ordering of `EventPlugin`s. A convenient way to reason about * plugins, without having to package every one of them. This is better than * having plugins be ordered in the same order that they are injected because * that ordering would be influenced by the packaging order. * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that * preventing default on events is convenient in `SimpleEventPlugin` handlers. */
var DefaultEventPluginOrder = [
keyOf({ResponderEventPlugin: null}), keyOf({SimpleEventPlugin: null}), keyOf({TapEventPlugin: null}), keyOf({EnterLeaveEventPlugin: null}), keyOf({ChangeEventPlugin: null}), keyOf({SelectEventPlugin: null}), keyOf({CompositionEventPlugin: null}), keyOf({AnalyticsEventPlugin: null}), keyOf({MobileSafariClickEventPlugin: null})
];
module.exports = DefaultEventPluginOrder;
},{“./keyOf”:132}],14:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule EnterLeaveEventPlugin * @typechecks static-only */
“use strict”;
var EventConstants = dereq(“./EventConstants”); var EventPropagators = dereq(“./EventPropagators”); var SyntheticMouseEvent = dereq(“./SyntheticMouseEvent”);
var ReactMount = dereq(“./ReactMount”); var keyOf = dereq(“./keyOf”);
var topLevelTypes = EventConstants.topLevelTypes; var getFirstReactDOM = ReactMount.getFirstReactDOM;
var eventTypes = {
mouseEnter: { registrationName: keyOf({onMouseEnter: null}), dependencies: [ topLevelTypes.topMouseOut, topLevelTypes.topMouseOver ] }, mouseLeave: { registrationName: keyOf({onMouseLeave: null}), dependencies: [ topLevelTypes.topMouseOut, topLevelTypes.topMouseOver ] }
};
var extractedEvents = [null, null];
var EnterLeaveEventPlugin = {
eventTypes: eventTypes, /** * For almost every interaction we care about, there will be both a top-level * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that * 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) { if (topLevelType === topLevelTypes.topMouseOver && (nativeEvent.relatedTarget || nativeEvent.fromElement)) { return null; } if (topLevelType !== topLevelTypes.topMouseOut && topLevelType !== topLevelTypes.topMouseOver) { // Must not be a mouse in or mouse out - ignoring. return null; } var win; if (topLevelTarget.window === topLevelTarget) { // `topLevelTarget` is probably a window object. win = topLevelTarget; } else { // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8. var doc = topLevelTarget.ownerDocument; if (doc) { win = doc.defaultView || doc.parentWindow; } else { win = window; } } var from, to; if (topLevelType === topLevelTypes.topMouseOut) { from = topLevelTarget; to = getFirstReactDOM(nativeEvent.relatedTarget || nativeEvent.toElement) || win; } else { from = win; to = topLevelTarget; } if (from === to) { // Nothing pertains to our managed components. return null; } var fromID = from ? ReactMount.getID(from) : ''; var toID = to ? ReactMount.getID(to) : ''; var leave = SyntheticMouseEvent.getPooled( eventTypes.mouseLeave, fromID, nativeEvent ); leave.type = 'mouseleave'; leave.target = from; leave.relatedTarget = to; var enter = SyntheticMouseEvent.getPooled( eventTypes.mouseEnter, toID, nativeEvent ); enter.type = 'mouseenter'; enter.target = to; enter.relatedTarget = from; EventPropagators.accumulateEnterLeaveDispatches(leave, enter, fromID, toID); extractedEvents[0] = leave; extractedEvents[1] = enter; return extractedEvents; }
};
module.exports = EnterLeaveEventPlugin;
},{“./EventConstants”:15,“./EventPropagators”:20,“./ReactMount”:60,“./SyntheticMouseEvent”:92,“./keyOf”:132}],15:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule EventConstants */
“use strict”;
var keyMirror = dereq(“./keyMirror”);
var PropagationPhases = keyMirror({bubbled: null, captured: null});
/**
* Types of raw signals from the browser caught at the top level. */
var topLevelTypes = keyMirror({
topBlur: null, topChange: null, topClick: null, topCompositionEnd: null, topCompositionStart: null, topCompositionUpdate: null, topContextMenu: null, topCopy: null, topCut: null, topDoubleClick: null, topDrag: null, topDragEnd: null, topDragEnter: null, topDragExit: null, topDragLeave: null, topDragOver: null, topDragStart: null, topDrop: null, topError: null, topFocus: null, topInput: null, topKeyDown: null, topKeyPress: null, topKeyUp: null, topLoad: null, topMouseDown: null, topMouseMove: null, topMouseOut: null, topMouseOver: null, topMouseUp: null, topPaste: null, topReset: null, topScroll: null, topSelectionChange: null, topSubmit: null, topTouchCancel: null, topTouchEnd: null, topTouchMove: null, topTouchStart: null, topWheel: null
});
var EventConstants = {
topLevelTypes: topLevelTypes, PropagationPhases: PropagationPhases
};
module.exports = EventConstants;
},{“./keyMirror”:131}],16:[function(dereq,module,exports){ /**
* @providesModule EventListener */
var emptyFunction = dereq(“./emptyFunction”);
/**
* Upstream version of event listener. Does not take into account specific * nature of platform. */
var EventListener = {
/** * Listen to DOM events during the bubble phase. * * @param {DOMEventTarget} target DOM element to register listener on. * @param {string} eventType Event type, e.g. 'click' or 'mouseover'. * @param {function} callback Callback function. * @return {object} Object with a `remove` method. */ listen: function(target, eventType, callback) { if (target.addEventListener) { target.addEventListener(eventType, callback, false); return { remove: function() { target.removeEventListener(eventType, callback, false); } }; } else if (target.attachEvent) { target.attachEvent('on' + eventType, callback); return { remove: function() { target.detachEvent(eventType, callback); } }; } }, /** * Listen to DOM events during the capture phase. * * @param {DOMEventTarget} target DOM element to register listener on. * @param {string} eventType Event type, e.g. 'click' or 'mouseover'. * @param {function} callback Callback function. * @return {object} Object with a `remove` method. */ capture: function(target, eventType, callback) { if (!target.addEventListener) { if ("production" !== "development") { console.error( 'Attempted to listen to events during the capture phase on a ' + 'browser that does not support the capture phase. Your application ' + 'will not receive some events.' ); } return { remove: emptyFunction }; } else { target.addEventListener(eventType, callback, true); return { remove: function() { target.removeEventListener(eventType, callback, true); } }; } }
};
module.exports = EventListener;
},{“./emptyFunction”:109}],17:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule EventPluginHub */
“use strict”;
var EventPluginRegistry = dereq(“./EventPluginRegistry”); var EventPluginUtils = dereq(“./EventPluginUtils”); var ExecutionEnvironment = dereq(“./ExecutionEnvironment”);
var accumulate = dereq(“./accumulate”); var forEachAccumulated = dereq(“./forEachAccumulated”); var invariant = dereq(“./invariant”); var isEventSupported = dereq(“./isEventSupported”); var monitorCodeUse = dereq(“./monitorCodeUse”);
/**
* Internal store for event listeners */
var listenerBank = {};
/**
* Internal queue of events that have accumulated their dispatches and are * waiting to have their dispatches executed. */
var eventQueue = null;
/**
* Dispatches an event and releases it back into the pool, unless persistent. * * @param {?object} event Synthetic event to be dispatched. * @private */
var executeDispatchesAndRelease = function(event) {
if (event) { var executeDispatch = EventPluginUtils.executeDispatch; // Plugins can provide custom behavior when dispatching events. var PluginModule = EventPluginRegistry.getPluginModuleForEvent(event); if (PluginModule && PluginModule.executeDispatch) { executeDispatch = PluginModule.executeDispatch; } EventPluginUtils.executeDispatchesInOrder(event, executeDispatch); if (!event.isPersistent()) { event.constructor.release(event); } }
};
/**
* - `InstanceHandle`: [required] Module that performs logical traversals of DOM * hierarchy given ids of the logical DOM elements involved. */
var InstanceHandle = null;
function validateInstanceHandle() {
var invalid = !InstanceHandle|| !InstanceHandle.traverseTwoPhase || !InstanceHandle.traverseEnterLeave; if (invalid) { throw new Error('InstanceHandle not injected before use!'); }
}
/**
* This is a unified interface for event plugins to be installed and configured. * * Event plugins can implement the following properties: * * `extractEvents` {function(string, DOMEventTarget, string, object): *} * Required. When a top-level event is fired, this method is expected to * extract synthetic events that will in turn be queued and dispatched. * * `eventTypes` {object} * Optional, plugins that fire events must publish a mapping of registration * names that are used to register listeners. Values of this mapping must * be objects that contain `registrationName` or `phasedRegistrationNames`. * * `executeDispatch` {function(object, function, string)} * Optional, allows plugins to override how an event gets dispatched. By * default, the listener is simply invoked. * * Each plugin that is injected into `EventsPluginHub` is immediately operable. * * @public */
var EventPluginHub = {
/** * Methods for injecting dependencies. */ injection: { /** * @param {object} InjectedMount * @public */ injectMount: EventPluginUtils.injection.injectMount, /** * @param {object} InjectedInstanceHandle * @public */ injectInstanceHandle: function(InjectedInstanceHandle) { InstanceHandle = InjectedInstanceHandle; if ("production" !== "development") { validateInstanceHandle(); } }, getInstanceHandle: function() { if ("production" !== "development") { validateInstanceHandle(); } return InstanceHandle; }, /** * @param {array} InjectedEventPluginOrder * @public */ injectEventPluginOrder: EventPluginRegistry.injectEventPluginOrder, /** * @param {object} injectedNamesToPlugins Map from names to plugin modules. */ injectEventPluginsByName: EventPluginRegistry.injectEventPluginsByName }, eventNameDispatchConfigs: EventPluginRegistry.eventNameDispatchConfigs, registrationNameModules: EventPluginRegistry.registrationNameModules, /** * Stores `listener` at `listenerBank[registrationName][id]`. Is idempotent. * * @param {string} id ID of the DOM element. * @param {string} registrationName Name of listener (e.g. `onClick`). * @param {?function} listener The callback to store. */ putListener: function(id, registrationName, listener) { ("production" !== "development" ? invariant( ExecutionEnvironment.canUseDOM, 'Cannot call putListener() in a non-DOM environment.' ) : invariant(ExecutionEnvironment.canUseDOM)); ("production" !== "development" ? invariant( !listener || typeof listener === 'function', 'Expected %s listener to be a function, instead got type %s', registrationName, typeof listener ) : invariant(!listener || typeof listener === 'function')); if ("production" !== "development") { // IE8 has no API for event capturing and the `onScroll` event doesn't // bubble. if (registrationName === 'onScroll' && !isEventSupported('scroll', true)) { monitorCodeUse('react_no_scroll_event'); console.warn('This browser doesn\'t support the `onScroll` event'); } } var bankForRegistrationName = listenerBank[registrationName] || (listenerBank[registrationName] = {}); bankForRegistrationName[id] = listener; }, /** * @param {string} id ID of the DOM element. * @param {string} registrationName Name of listener (e.g. `onClick`). * @return {?function} The stored callback. */ getListener: function(id, registrationName) { var bankForRegistrationName = listenerBank[registrationName]; return bankForRegistrationName && bankForRegistrationName[id]; }, /** * Deletes a listener from the registration bank. * * @param {string} id ID of the DOM element. * @param {string} registrationName Name of listener (e.g. `onClick`). */ deleteListener: function(id, registrationName) { var bankForRegistrationName = listenerBank[registrationName]; if (bankForRegistrationName) { delete bankForRegistrationName[id]; } }, /** * Deletes all listeners for the DOM element with the supplied ID. * * @param {string} id ID of the DOM element. */ deleteAllListeners: function(id) { for (var registrationName in listenerBank) { delete listenerBank[registrationName][id]; } }, /** * 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) { var events; var plugins = EventPluginRegistry.plugins; for (var i = 0, l = plugins.length; i < l; 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 ); if (extractedEvents) { events = accumulate(events, extractedEvents); } } } return events; }, /** * Enqueues a synthetic event that should be dispatched when * `processEventQueue` is invoked. * * @param {*} events An accumulation of synthetic events. * @internal */ enqueueEvents: function(events) { if (events) { eventQueue = accumulate(eventQueue, events); } }, /** * Dispatches all synthetic events on the event queue. * * @internal */ processEventQueue: function() { // Set `eventQueue` to null before processing it so that we can tell if more // events get enqueued while processing. var processingEventQueue = eventQueue; eventQueue = null; forEachAccumulated(processingEventQueue, executeDispatchesAndRelease); ("production" !== "development" ? invariant( !eventQueue, 'processEventQueue(): Additional events were enqueued while processing ' + 'an event queue. Support for this has not yet been implemented.' ) : invariant(!eventQueue)); }, /** * These are needed for tests only. Do not use! */ __purge: function() { listenerBank = {}; }, __getListenerBank: function() { return listenerBank; }
};
module.exports = EventPluginHub;
},{“./EventPluginRegistry”:18,“./EventPluginUtils”:19,“./ExecutionEnvironment”:21,“./accumulate”:98,“./forEachAccumulated”:114,“./invariant”:125,“./isEventSupported”:126,“./monitorCodeUse”:138}],18:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule EventPluginRegistry * @typechecks static-only */
“use strict”;
var invariant = dereq(“./invariant”);
/**
* Injectable ordering of event plugins. */
var EventPluginOrder = null;
/**
* Injectable mapping from names to event plugin modules. */
var namesToPlugins = {};
/**
* Recomputes the plugin list using the injected plugins and plugin ordering. * * @private */
function recomputePluginOrdering() {
if (!EventPluginOrder) { // Wait until an `EventPluginOrder` is injected. return; } for (var pluginName in namesToPlugins) { var PluginModule = namesToPlugins[pluginName]; var pluginIndex = EventPluginOrder.indexOf(pluginName); ("production" !== "development" ? invariant( pluginIndex > -1, 'EventPluginRegistry: Cannot inject event plugins that do not exist in ' + 'the plugin ordering, `%s`.', pluginName ) : invariant(pluginIndex > -1)); if (EventPluginRegistry.plugins[pluginIndex]) { continue; } ("production" !== "development" ? invariant( PluginModule.extractEvents, 'EventPluginRegistry: Event plugins must implement an `extractEvents` ' + 'method, but `%s` does not.', pluginName ) : invariant(PluginModule.extractEvents)); EventPluginRegistry.plugins[pluginIndex] = PluginModule; var publishedEvents = PluginModule.eventTypes; for (var eventName in publishedEvents) { ("production" !== "development" ? invariant( publishEventForPlugin( publishedEvents[eventName], PluginModule, eventName ), 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', eventName, pluginName ) : invariant(publishEventForPlugin( publishedEvents[eventName], PluginModule, eventName ))); } }
}
/**
* Publishes an event so that it can be dispatched by the supplied plugin. * * @param {object} dispatchConfig Dispatch configuration for the event. * @param {object} PluginModule Plugin publishing the event. * @return {boolean} True if the event was successfully published. * @private */
function publishEventForPlugin(dispatchConfig, PluginModule, eventName) {
("production" !== "development" ? invariant( !EventPluginRegistry.eventNameDispatchConfigs[eventName], 'EventPluginHub: More than one plugin attempted to publish the same ' + 'event name, `%s`.', eventName ) : invariant(!EventPluginRegistry.eventNameDispatchConfigs[eventName])); EventPluginRegistry.eventNameDispatchConfigs[eventName] = dispatchConfig; var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; if (phasedRegistrationNames) { for (var phaseName in phasedRegistrationNames) { if (phasedRegistrationNames.hasOwnProperty(phaseName)) { var phasedRegistrationName = phasedRegistrationNames[phaseName]; publishRegistrationName( phasedRegistrationName, PluginModule, eventName ); } } return true; } else if (dispatchConfig.registrationName) { publishRegistrationName( dispatchConfig.registrationName, PluginModule, eventName ); return true; } return false;
}
/**
* Publishes a registration name that is used to identify dispatched events and * can be used with `EventPluginHub.putListener` to register listeners. * * @param {string} registrationName Registration name to add. * @param {object} PluginModule Plugin publishing the event. * @private */
function publishRegistrationName(registrationName, PluginModule, eventName) {
("production" !== "development" ? invariant( !EventPluginRegistry.registrationNameModules[registrationName], 'EventPluginHub: More than one plugin attempted to publish the same ' + 'registration name, `%s`.', registrationName ) : invariant(!EventPluginRegistry.registrationNameModules[registrationName])); EventPluginRegistry.registrationNameModules[registrationName] = PluginModule; EventPluginRegistry.registrationNameDependencies[registrationName] = PluginModule.eventTypes[eventName].dependencies;
}
/**
* Registers plugins so that they can extract and dispatch events. * * @see {EventPluginHub} */
var EventPluginRegistry = {
/** * Ordered list of injected plugins. */ plugins: [], /** * Mapping from event name to dispatch config */ eventNameDispatchConfigs: {}, /** * Mapping from registration name to plugin module */ registrationNameModules: {}, /** * Mapping from registration name to event name */ registrationNameDependencies: {}, /** * 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 * always deterministic regardless of packaging, on-the-fly injection, etc. * * @param {array} InjectedEventPluginOrder * @internal * @see {EventPluginHub.injection.injectEventPluginOrder} */ injectEventPluginOrder: function(InjectedEventPluginOrder) { ("production" !== "development" ? invariant( !EventPluginOrder, 'EventPluginRegistry: Cannot inject event plugin ordering more than once.' ) : invariant(!EventPluginOrder)); // Clone the ordering so it cannot be dynamically mutated. EventPluginOrder = Array.prototype.slice.call(InjectedEventPluginOrder); recomputePluginOrdering(); }, /** * Injects plugins to be used by `EventPluginHub`. The plugin names must be * in the ordering injected by `injectEventPluginOrder`. * * Plugins can be injected as part of page initialization or on-the-fly. * * @param {object} injectedNamesToPlugins Map from names to plugin modules. * @internal * @see {EventPluginHub.injection.injectEventPluginsByName} */ injectEventPluginsByName: function(injectedNamesToPlugins) { var isOrderingDirty = false; for (var pluginName in injectedNamesToPlugins) { if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { continue; } var PluginModule = injectedNamesToPlugins[pluginName]; if (namesToPlugins[pluginName] !== PluginModule) { ("production" !== "development" ? invariant( !namesToPlugins[pluginName], 'EventPluginRegistry: Cannot inject two different event plugins ' + 'using the same name, `%s`.', pluginName ) : invariant(!namesToPlugins[pluginName])); namesToPlugins[pluginName] = PluginModule; isOrderingDirty = true; } } if (isOrderingDirty) { recomputePluginOrdering(); } }, /** * Looks up the plugin for the supplied event. * * @param {object} event A synthetic event. * @return {?object} The plugin that created the supplied event. * @internal */ getPluginModuleForEvent: function(event) { var dispatchConfig = event.dispatchConfig; if (dispatchConfig.registrationName) { return EventPluginRegistry.registrationNameModules[ dispatchConfig.registrationName ] || null; } for (var phase in dispatchConfig.phasedRegistrationNames) { if (!dispatchConfig.phasedRegistrationNames.hasOwnProperty(phase)) { continue; } var PluginModule = EventPluginRegistry.registrationNameModules[ dispatchConfig.phasedRegistrationNames[phase] ]; if (PluginModule) { return PluginModule; } } return null; }, /** * Exposed for unit testing. * @private */ _resetEventPlugins: function() { EventPluginOrder = null; for (var pluginName in namesToPlugins) { if (namesToPlugins.hasOwnProperty(pluginName)) { delete namesToPlugins[pluginName]; } } EventPluginRegistry.plugins.length = 0; var eventNameDispatchConfigs = EventPluginRegistry.eventNameDispatchConfigs; for (var eventName in eventNameDispatchConfigs) { if (eventNameDispatchConfigs.hasOwnProperty(eventName)) { delete eventNameDispatchConfigs[eventName]; } } var registrationNameModules = EventPluginRegistry.registrationNameModules; for (var registrationName in registrationNameModules) { if (registrationNameModules.hasOwnProperty(registrationName)) { delete registrationNameModules[registrationName]; } } }
};
module.exports = EventPluginRegistry;
},{“./invariant”:125}],19:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule EventPluginUtils */
“use strict”;
var EventConstants = dereq(“./EventConstants”);
var invariant = dereq(“./invariant”);
/**
* Injected dependencies: */
/**
* - `Mount`: [required] Module that can convert between React dom IDs and * actual node references. */
var injection = {
Mount: null, injectMount: function(InjectedMount) { injection.Mount = InjectedMount; if ("production" !== "development") { ("production" !== "development" ? invariant( InjectedMount && InjectedMount.getNode, 'EventPluginUtils.injection.injectMount(...): Injected Mount module ' + 'is missing getNode.' ) : invariant(InjectedMount && InjectedMount.getNode)); } }
};
var topLevelTypes = EventConstants.topLevelTypes;
function isEndish(topLevelType) {
return topLevelType === topLevelTypes.topMouseUp || topLevelType === topLevelTypes.topTouchEnd || topLevelType === topLevelTypes.topTouchCancel;
}
function isMoveish(topLevelType) {
return topLevelType === topLevelTypes.topMouseMove || topLevelType === topLevelTypes.topTouchMove;
} function isStartish(topLevelType) {
return topLevelType === topLevelTypes.topMouseDown || topLevelType === topLevelTypes.topTouchStart;
}
var validateEventDispatches; if (“production” !== “development”) {
validateEventDispatches = function(event) { var dispatchListeners = event._dispatchListeners; var dispatchIDs = event._dispatchIDs; 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; ("production" !== "development" ? invariant( idsIsArr === listenersIsArr && IDsLen === listenersLen, 'EventPluginUtils: Invalid `event`.' ) : invariant(idsIsArr === listenersIsArr && IDsLen === listenersLen)); };
}
/**
* Invokes `cb(event, listener, id)`. Avoids using call if no scope is * provided. The `(listener,id)` pair effectively forms the "dispatch" but are * kept separate to conserve memory. */
function forEachEventDispatch(event, cb) {
var dispatchListeners = event._dispatchListeners; var dispatchIDs = event._dispatchIDs; if ("production" !== "development") { validateEventDispatches(event); } if (Array.isArray(dispatchListeners)) { for (var i = 0; i < dispatchListeners.length; i++) { if (event.isPropagationStopped()) { break; } // Listeners and IDs are two parallel arrays that are always in sync. cb(event, dispatchListeners[i], dispatchIDs[i]); } } else if (dispatchListeners) { cb(event, dispatchListeners, dispatchIDs); }
}
/**
* Default implementation of PluginModule.executeDispatch(). * @param {SyntheticEvent} SyntheticEvent to handle * @param {function} Application-level callback * @param {string} domID DOM id to pass to the callback. */
function executeDispatch(event, listener, domID) {
event.currentTarget = injection.Mount.getNode(domID); var returnValue = listener(event, domID); event.currentTarget = null; return returnValue;
}
/**
* Standard/simple iteration through an event's collected dispatches. */
function executeDispatchesInOrder(event, executeDispatch) {
forEachEventDispatch(event, executeDispatch); event._dispatchListeners = null; event._dispatchIDs = null;
}
/**
* Standard/simple iteration through an event's collected dispatches, but stops * at the first dispatch execution returning true, and returns that id. * * @return id of the first dispatch execution who's listener returns true, or * null if no listener returned true. */
function executeDispatchesInOrderStopAtTrue(event) {
var dispatchListeners = event._dispatchListeners; var dispatchIDs = event._dispatchIDs; if ("production" !== "development") { validateEventDispatches(event); } if (Array.isArray(dispatchListeners)) { for (var i = 0; i < dispatchListeners.length; i++) { 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]; } } } else if (dispatchListeners) { if (dispatchListeners(event, dispatchIDs)) { return dispatchIDs; } } return null;
}
/**
* Execution of a "direct" dispatch - there must be at most one dispatch * accumulated on the event or it is considered an error. It doesn't really make * sense for an event with multiple dispatches (bubbled) to keep track of the * return values at each dispatch execution, but it does tend to make sense when * dealing with "direct" dispatches. * * @return The return value of executing the single dispatch. */
function executeDirectDispatch(event) {
if ("production" !== "development") { validateEventDispatches(event); } var dispatchListener = event._dispatchListeners; var dispatchID = event._dispatchIDs; ("production" !== "development" ? invariant( !Array.isArray(dispatchListener), 'executeDirectDispatch(...): Invalid `event`.' ) : invariant(!Array.isArray(dispatchListener))); var res = dispatchListener ? dispatchListener(event, dispatchID) : null; event._dispatchListeners = null; event._dispatchIDs = null; return res;
}
/**
* @param {SyntheticEvent} event * @return {bool} True iff number of dispatches accumulated is greater than 0. */
function hasDispatches(event) {
return !!event._dispatchListeners;
}
/**
* General utilities that are useful in creating custom Event Plugins. */
var EventPluginUtils = {
isEndish: isEndish, isMoveish: isMoveish, isStartish: isStartish, executeDirectDispatch: executeDirectDispatch, executeDispatch: executeDispatch, executeDispatchesInOrder: executeDispatchesInOrder, executeDispatchesInOrderStopAtTrue: executeDispatchesInOrderStopAtTrue, hasDispatches: hasDispatches, injection: injection, useTouchEvents: false
};
module.exports = EventPluginUtils;
},{“./EventConstants”:15,“./invariant”:125}],20:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule EventPropagators */
“use strict”;
var EventConstants = dereq(“./EventConstants”); var EventPluginHub = dereq(“./EventPluginHub”);
var accumulate = dereq(“./accumulate”); var forEachAccumulated = dereq(“./forEachAccumulated”);
var PropagationPhases = EventConstants.PropagationPhases; 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) {
var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase]; return getListener(id, registrationName);
}
/**
* Tags a `SyntheticEvent` with dispatched listeners. Creating this function * here, allows us to not have to bind or create functions for each event. * 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) {
if ("production" !== "development") { if (!domID) { throw new Error('Dispatching id must not be null'); } } var phase = upwards ? PropagationPhases.bubbled : PropagationPhases.captured; var listener = listenerAtPhase(domID, event, phase); if (listener) { event._dispatchListeners = accumulate(event._dispatchListeners, listener); event._dispatchIDs = accumulate(event._dispatchIDs, domID); }
}
/**
* Collect dispatches (must be entirely collected before dispatching - see unit * tests). Lazily allocate the array to conserve memory. We must loop through * each event and perform the traversal for each one. We can not perform a * single traversal for the entire collection of events because each event may * have a different target. */
function accumulateTwoPhaseDispatchesSingle(event) {
if (event && event.dispatchConfig.phasedRegistrationNames) { EventPluginHub.injection.getInstanceHandle().traverseTwoPhase( event.dispatchMarker, accumulateDirectionalDispatches, event ); }
}
/**
* Accumulates without regard to direction, does not look for phased * registration names. Same as `accumulateDirectDispatchesSingle` but without * requiring that the `dispatchMarker` be the same as the dispatched ID. */
function accumulateDispatches(id, ignoredDirection, event) {
if (event && event.dispatchConfig.registrationName) { var registrationName = event.dispatchConfig.registrationName; var listener = getListener(id, registrationName); if (listener) { event._dispatchListeners = accumulate(event._dispatchListeners, listener); event._dispatchIDs = accumulate(event._dispatchIDs, id); } }
}
/**
* Accumulates dispatches on an `SyntheticEvent`, but only for the * `dispatchMarker`. * @param {SyntheticEvent} event */
function accumulateDirectDispatchesSingle(event) {
if (event && event.dispatchConfig.registrationName) { accumulateDispatches(event.dispatchMarker, null, event); }
}
function accumulateTwoPhaseDispatches(events) {
forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
}
function accumulateEnterLeaveDispatches(leave, enter, fromID, toID) {
EventPluginHub.injection.getInstanceHandle().traverseEnterLeave( fromID, toID, accumulateDispatches, leave, enter );
}
function accumulateDirectDispatches(events) {
forEachAccumulated(events, accumulateDirectDispatchesSingle);
}
/**
* A small set of propagation patterns, each of which will accept a small amount * of information, and generate a set of "dispatch ready event objects" - which * are sets of events that have already been annotated with a set of dispatched * listener functions/ids. The API is designed this way to discourage these * propagation strategies from actually executing the dispatches, since we * always want to collect the entire set of dispatches before executing event a * single one. * * @constructor EventPropagators */
var EventPropagators = {
accumulateTwoPhaseDispatches: accumulateTwoPhaseDispatches, accumulateDirectDispatches: accumulateDirectDispatches, accumulateEnterLeaveDispatches: accumulateEnterLeaveDispatches
};
module.exports = EventPropagators;
},{“./EventConstants”:15,“./EventPluginHub”:17,“./accumulate”:98,“./forEachAccumulated”:114}],21:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ExecutionEnvironment */
/*jslint evil: true */
“use strict”;
var canUseDOM = typeof window !== 'undefined';
/**
* Simple, lightweight module assisting with the detection and context of * Worker. Helps avoid circular dependencies and allows code to reason about * whether or not they are in a Worker, even if they never include the main * `ReactWorker` dependency. */
var ExecutionEnvironment = {
canUseDOM: canUseDOM, canUseWorkers: typeof Worker !== 'undefined', canUseEventListeners: canUseDOM && (window.addEventListener || window.attachEvent), isInWorker: !canUseDOM // For now, this is true - might change in the future.
};
module.exports = ExecutionEnvironment;
},{}],22:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule LinkedStateMixin * @typechecks static-only */
“use strict”;
var ReactLink = dereq(“./ReactLink”); var ReactStateSetters = dereq(“./ReactStateSetters”);
/**
* A simple mixin around ReactLink.forState(). */
var LinkedStateMixin = {
/** * Create a ReactLink that's linked to part of this component's state. The * ReactLink will have the current value of this.state[key] and will call * setState() when a change is requested. * * @param {string} key state key to update. Note: you may want to use keyOf() * if you're using Google Closure Compiler advanced mode. * @return {ReactLink} ReactLink instance linking to the state. */ linkState: function(key) { return new ReactLink( this.state[key], ReactStateSetters.createStateKeySetter(this, key) ); }
};
module.exports = LinkedStateMixin;
},{“./ReactLink”:58,“./ReactStateSetters”:75}],23:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule LinkedValueUtils * @typechecks static-only */
“use strict”;
var ReactPropTypes = dereq(“./ReactPropTypes”);
var invariant = dereq(“./invariant”); var warning = dereq(“./warning”);
var hasReadOnlyValue = {
'button': true, 'checkbox': true, 'image': true, 'hidden': true, 'radio': true, 'reset': true, 'submit': true
};
function _assertSingleLink(input) {
("production" !== "development" ? invariant( input.props.checkedLink == null || input.props.valueLink == null, 'Cannot provide a checkedLink and a valueLink. If you want to use ' + 'checkedLink, you probably don\'t want to use valueLink and vice versa.' ) : invariant(input.props.checkedLink == null || input.props.valueLink == null));
} function _assertValueLink(input) {
_assertSingleLink(input); ("production" !== "development" ? invariant( input.props.value == null && input.props.onChange == null, 'Cannot provide a valueLink and a value or onChange event. If you want ' + 'to use value or onChange, you probably don\'t want to use valueLink.' ) : invariant(input.props.value == null && input.props.onChange == null));
}
function _assertCheckedLink(input) {
_assertSingleLink(input); ("production" !== "development" ? invariant( input.props.checked == null && input.props.onChange == null, 'Cannot provide a checkedLink and a checked property or onChange event. ' + 'If you want to use checked or onChange, you probably don\'t want to ' + 'use checkedLink' ) : invariant(input.props.checked == null && input.props.onChange == null));
}
/**
* @param {SyntheticEvent} e change event to handle */
function _handleLinkedValueChange(e) {
/*jshint validthis:true */ this.props.valueLink.requestChange(e.target.value);
}
/**
* @param {SyntheticEvent} e change event to handle */
function _handleLinkedCheckChange(e) {
/*jshint validthis:true */ this.props.checkedLink.requestChange(e.target.checked);
}
/**
* Provide a linked `value` attribute for controlled forms. You should not use * this outside of the ReactDOM controlled form components. */
var LinkedValueUtils = {
Mixin: { propTypes: { value: function(props, propName, componentName) { if ("production" !== "development") { ("production" !== "development" ? warning( !props[propName] || hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled, 'You provided a `value` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultValue`. Otherwise, ' + 'set either `onChange` or `readOnly`.' ) : null); } }, checked: function(props, propName, componentName) { if ("production" !== "development") { ("production" !== "development" ? warning( !props[propName] || props.onChange || props.readOnly || props.disabled, 'You provided a `checked` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultChecked`. Otherwise, ' + 'set either `onChange` or `readOnly`.' ) : null); } }, onChange: ReactPropTypes.func } }, /** * @param {ReactComponent} input Form component * @return {*} current value of the input either from value prop or link. */ getValue: function(input) { if (input.props.valueLink) { _assertValueLink(input); return input.props.valueLink.value; } return input.props.value; }, /** * @param {ReactComponent} input Form component * @return {*} current checked status of the input either from checked prop * or link. */ getChecked: function(input) { if (input.props.checkedLink) { _assertCheckedLink(input); return input.props.checkedLink.value; } return input.props.checked; }, /** * @param {ReactComponent} input Form component * @return {function} change callback either from onChange prop or link. */ getOnChange: function(input) { if (input.props.valueLink) { _assertValueLink(input); return _handleLinkedValueChange; } else if (input.props.checkedLink) { _assertCheckedLink(input); return _handleLinkedCheckChange; } return input.props.onChange; }
};
module.exports = LinkedValueUtils;
},{“./ReactPropTypes”:69,“./invariant”:125,“./warning”:148}],24:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule MobileSafariClickEventPlugin * @typechecks static-only */
“use strict”;
var EventConstants = dereq(“./EventConstants”);
var emptyFunction = dereq(“./emptyFunction”);
var topLevelTypes = EventConstants.topLevelTypes;
/**
* Mobile Safari does not fire properly bubble click events on non-interactive * elements, which means delegated click listeners do not fire. The workaround * for this bug involves attaching an empty click listener on the target node. * * This particular plugin works around the bug by attaching an empty click * listener on `touchstart` (which does fire on every element). */
var MobileSafariClickEventPlugin = {
eventTypes: null, /** * @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) { if (topLevelType === topLevelTypes.topTouchStart) { var target = nativeEvent.target; if (target && !target.onclick) { target.onclick = emptyFunction; } } }
};
module.exports = MobileSafariClickEventPlugin;
},{“./EventConstants”:15,“./emptyFunction”:109}],25:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule PooledClass */
“use strict”;
var invariant = dereq(“./invariant”);
/**
* Static poolers. Several custom versions for each potential number of * arguments. A completely generic pooler is easy to implement, but would * require accessing the `arguments` object. In each of these, `this` refers to * the Class itself, not an instance. If any others are needed, simply add them * here, or in their own files. */
var oneArgumentPooler = function(copyFieldsFrom) {
var Klass = this; if (Klass.instancePool.length) { var instance = Klass.instancePool.pop(); Klass.call(instance, copyFieldsFrom); return instance; } else { return new Klass(copyFieldsFrom); }
};
var twoArgumentPooler = function(a1, a2) {
var Klass = this; if (Klass.instancePool.length) { var instance = Klass.instancePool.pop(); Klass.call(instance, a1, a2); return instance; } else { return new Klass(a1, a2); }
};
var threeArgumentPooler = function(a1, a2, a3) {
var Klass = this; if (Klass.instancePool.length) { var instance = Klass.instancePool.pop(); Klass.call(instance, a1, a2, a3); return instance; } else { return new Klass(a1, a2, a3); }
};
var fiveArgumentPooler = function(a1, a2, a3, a4, a5) {
var Klass = this; if (Klass.instancePool.length) { var instance = Klass.instancePool.pop(); Klass.call(instance, a1, a2, a3, a4, a5); return instance; } else { return new Klass(a1, a2, a3, a4, a5); }
};
var standardReleaser = function(instance) {
var Klass = this; ("production" !== "development" ? invariant( instance instanceof Klass, 'Trying to release an instance into a pool of a different type.' ) : invariant(instance instanceof Klass)); if (instance.destructor) { instance.destructor(); } if (Klass.instancePool.length < Klass.poolSize) { Klass.instancePool.push(instance); }
};
var DEFAULT_POOL_SIZE = 10; var DEFAULT_POOLER = oneArgumentPooler;
/**
* Augments `CopyConstructor` to be a poolable class, augmenting only the class * itself (statically) not adding any prototypical fields. Any CopyConstructor * you give this may have a `poolSize` property, and will look for a * prototypical `destructor` on instances (optional). * * @param {Function} CopyConstructor Constructor that can be used to reset. * @param {Function} pooler Customizable pooler. */
var addPoolingTo = function(CopyConstructor, pooler) {
var NewKlass = CopyConstructor; NewKlass.instancePool = []; NewKlass.getPooled = pooler || DEFAULT_POOLER; if (!NewKlass.poolSize) { NewKlass.poolSize = DEFAULT_POOL_SIZE; } NewKlass.release = standardReleaser; return NewKlass;
};
var PooledClass = {
addPoolingTo: addPoolingTo, oneArgumentPooler: oneArgumentPooler, twoArgumentPooler: twoArgumentPooler, threeArgumentPooler: threeArgumentPooler, fiveArgumentPooler: fiveArgumentPooler
};
module.exports = PooledClass;
},{“./invariant”:125}],26:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule React */
“use strict”;
var DOMPropertyOperations = dereq(“./DOMPropertyOperations”); var EventPluginUtils = dereq(“./EventPluginUtils”); var ReactChildren = dereq(“./ReactChildren”); var ReactComponent = dereq(“./ReactComponent”); var ReactCompositeComponent = dereq(“./ReactCompositeComponent”); var ReactContext = dereq(“./ReactContext”); var ReactCurrentOwner = dereq(“./ReactCurrentOwner”); var ReactDOM = dereq(“./ReactDOM”); var ReactDOMComponent = dereq(“./ReactDOMComponent”); var ReactDefaultInjection = dereq(“./ReactDefaultInjection”); var ReactInstanceHandles = dereq(“./ReactInstanceHandles”); var ReactMount = dereq(“./ReactMount”); var ReactMultiChild = dereq(“./ReactMultiChild”); var ReactPerf = dereq(“./ReactPerf”); var ReactPropTypes = dereq(“./ReactPropTypes”); var ReactServerRendering = dereq(“./ReactServerRendering”); var ReactTextComponent = dereq(“./ReactTextComponent”);
var onlyChild = dereq(“./onlyChild”);
ReactDefaultInjection.inject();
var React = {
Children: { map: ReactChildren.map, forEach: ReactChildren.forEach, only: onlyChild }, DOM: ReactDOM, PropTypes: ReactPropTypes, initializeTouchEvents: function(shouldUseTouch) { EventPluginUtils.useTouchEvents = shouldUseTouch; }, createClass: ReactCompositeComponent.createClass, constructAndRenderComponent: ReactMount.constructAndRenderComponent, constructAndRenderComponentByID: ReactMount.constructAndRenderComponentByID, renderComponent: ReactPerf.measure( 'React', 'renderComponent', ReactMount.renderComponent ), renderComponentToString: ReactServerRendering.renderComponentToString, renderComponentToStaticMarkup: ReactServerRendering.renderComponentToStaticMarkup, unmountComponentAtNode: ReactMount.unmountComponentAtNode, isValidClass: ReactCompositeComponent.isValidClass, isValidComponent: ReactComponent.isValidComponent, withContext: ReactContext.withContext, __internals: { Component: ReactComponent, CurrentOwner: ReactCurrentOwner, DOMComponent: ReactDOMComponent, DOMPropertyOperations: DOMPropertyOperations, InstanceHandles: ReactInstanceHandles, Mount: ReactMount, MultiChild: ReactMultiChild, TextComponent: ReactTextComponent }
};
if (“production” !== “development”) {
var ExecutionEnvironment = _dereq_("./ExecutionEnvironment"); if (ExecutionEnvironment.canUseDOM && window.top === window.self && navigator.userAgent.indexOf('Chrome') > -1) { console.debug( 'Download the React DevTools for a better development experience: ' + 'http://fb.me/react-devtools' ); }
}
// Version exists only in the open-source version of React, not in Facebook's // internal version. React.version = '0.10.0';
module.exports = React;
},{“./DOMPropertyOperations”:10,“./EventPluginUtils”:19,“./ExecutionEnvironment”:21,“./ReactChildren”:30,“./ReactComponent”:31,“./ReactCompositeComponent”:33,“./ReactContext”:34,“./ReactCurrentOwner”:35,“./ReactDOM”:36,“./ReactDOMComponent”:38,“./ReactDefaultInjection”:48,“./ReactInstanceHandles”:57,“./ReactMount”:60,“./ReactMultiChild”:62,“./ReactPerf”:65,“./ReactPropTypes”:69,“./ReactServerRendering”:73,“./ReactTextComponent”:77,“./onlyChild”:141}],27:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactBrowserComponentMixin */
“use strict”;
var ReactMount = dereq(“./ReactMount”);
var invariant = dereq(“./invariant”);
var ReactBrowserComponentMixin = {
/** * Returns the DOM node rendered by this component. * * @return {DOMElement} The root node of this component. * @final * @protected */ getDOMNode: function() { ("production" !== "development" ? invariant( this.isMounted(), 'getDOMNode(): A component must be mounted to have a DOM node.' ) : invariant(this.isMounted())); return ReactMount.getNode(this._rootNodeID); }
};
module.exports = ReactBrowserComponentMixin;
},{“./ReactMount”:60,“./invariant”:125}],28:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @typechecks * @providesModule ReactCSSTransitionGroup */
“use strict”;
var React = dereq(“./React”);
var ReactTransitionGroup = dereq(“./ReactTransitionGroup”); var ReactCSSTransitionGroupChild = dereq(“./ReactCSSTransitionGroupChild”);
var ReactCSSTransitionGroup = React.createClass({
propTypes: { transitionName: React.PropTypes.string.isRequired, transitionEnter: React.PropTypes.bool, transitionLeave: React.PropTypes.bool }, getDefaultProps: function() { return { transitionEnter: true, transitionLeave: true }; }, _wrapChild: function(child) { // We need to provide this childFactory so that // ReactCSSTransitionGroupChild can receive updates to name, enter, and // leave while it is leaving. return ReactCSSTransitionGroupChild( { name: this.props.transitionName, enter: this.props.transitionEnter, leave: this.props.transitionLeave }, child ); }, render: function() { return this.transferPropsTo( ReactTransitionGroup( {childFactory: this._wrapChild}, this.props.children ) ); }
});
module.exports = ReactCSSTransitionGroup;
},{“./React”:26,“./ReactCSSTransitionGroupChild”:29,“./ReactTransitionGroup”:80}],29:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @typechecks * @providesModule ReactCSSTransitionGroupChild */
“use strict”;
var React = dereq(“./React”);
var CSSCore = dereq(“./CSSCore”); var ReactTransitionEvents = dereq(“./ReactTransitionEvents”);
var onlyChild = dereq(“./onlyChild”);
// We don't remove the element from the DOM until we receive an animationend or // transitionend event. If the user screws up and forgets to add an animation // their node will be stuck in the DOM forever, so we detect if an animation // does not start and if it doesn't, we just call the end listener immediately. var TICK = 17; var NO_EVENT_TIMEOUT = 5000;
var noEventListener = null;
if (“production” !== “development”) {
noEventListener = function() { console.warn( 'transition(): tried to perform an animation without ' + 'an animationend or transitionend event after timeout (' + NO_EVENT_TIMEOUT + 'ms). You should either disable this ' + 'transition in JS or add a CSS animation/transition.' ); };
}
var ReactCSSTransitionGroupChild = React.createClass({
transition: function(animationType, finishCallback) { var node = this.getDOMNode(); var className = this.props.name + '-' + animationType; var activeClassName = className + '-active'; var noEventTimeout = null; var endListener = function() { if ("production" !== "development") { clearTimeout(noEventTimeout); } CSSCore.removeClass(node, className); CSSCore.removeClass(node, activeClassName); ReactTransitionEvents.removeEndEventListener(node, endListener); // Usually this optional callback is used for informing an owner of // a leave animation and telling it to remove the child. finishCallback && finishCallback(); }; ReactTransitionEvents.addEndEventListener(node, endListener); CSSCore.addClass(node, className); // Need to do this to actually trigger a transition. this.queueClass(activeClassName); if ("production" !== "development") { noEventTimeout = setTimeout(noEventListener, NO_EVENT_TIMEOUT); } }, queueClass: function(className) { this.classNameQueue.push(className); if (this.props.runNextTick) { this.props.runNextTick(this.flushClassNameQueue); return; } if (!this.timeout) { this.timeout = setTimeout(this.flushClassNameQueue, TICK); } }, flushClassNameQueue: function() { if (this.isMounted()) { this.classNameQueue.forEach( CSSCore.addClass.bind(CSSCore, this.getDOMNode()) ); } this.classNameQueue.length = 0; this.timeout = null; }, componentWillMount: function() { this.classNameQueue = []; }, componentWillUnmount: function() { if (this.timeout) { clearTimeout(this.timeout); } }, componentWillEnter: function(done) { if (this.props.enter) { this.transition('enter', done); } else { done(); } }, componentWillLeave: function(done) { if (this.props.leave) { this.transition('leave', done); } else { done(); } }, render: function() { return onlyChild(this.props.children); }
});
module.exports = ReactCSSTransitionGroupChild;
},{“./CSSCore”:2,“./React”:26,“./ReactTransitionEvents”:79,“./onlyChild”:141}],30:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactChildren */
“use strict”;
var PooledClass = dereq(“./PooledClass”);
var invariant = dereq(“./invariant”); var traverseAllChildren = dereq(“./traverseAllChildren”);
var twoArgumentPooler = PooledClass.twoArgumentPooler; var threeArgumentPooler = PooledClass.threeArgumentPooler;
/**
* PooledClass representing the bookkeeping associated with performing a child * traversal. Allows avoiding binding callbacks. * * @constructor ForEachBookKeeping * @param {!function} forEachFunction Function to perform traversal with. * @param {?*} forEachContext Context to perform context with. */
function ForEachBookKeeping(forEachFunction, forEachContext) {
this.forEachFunction = forEachFunction; this.forEachContext = forEachContext;
} PooledClass.addPoolingTo(ForEachBookKeeping, twoArgumentPooler);
function forEachSingleChild(traverseContext, child, name, i) {
var forEachBookKeeping = traverseContext; forEachBookKeeping.forEachFunction.call( forEachBookKeeping.forEachContext, child, i);
}
/**
* Iterates through children that are typically specified as `props.children`. * * The provided forEachFunc(child, index) will be called for each * leaf child. * * @param {?*} children Children tree container. * @param {function(*, int)} forEachFunc. * @param {*} forEachContext Context for forEachContext. */
function forEachChildren(children, forEachFunc, forEachContext) {
if (children == null) { return children; } var traverseContext = ForEachBookKeeping.getPooled(forEachFunc, forEachContext); traverseAllChildren(children, forEachSingleChild, traverseContext); ForEachBookKeeping.release(traverseContext);
}
/**
* PooledClass representing the bookkeeping associated with performing a child * mapping. Allows avoiding binding callbacks. * * @constructor MapBookKeeping * @param {!*} mapResult Object containing the ordered map of results. * @param {!function} mapFunction Function to perform mapping with. * @param {?*} mapContext Context to perform mapping with. */
function MapBookKeeping(mapResult, mapFunction, mapContext) {
this.mapResult = mapResult; this.mapFunction = mapFunction; this.mapContext = mapContext;
} PooledClass.addPoolingTo(MapBookKeeping, threeArgumentPooler);
function mapSingleChildIntoContext(traverseContext, child, name, i) {
var mapBookKeeping = traverseContext; var mapResult = mapBookKeeping.mapResult; var mappedChild = mapBookKeeping.mapFunction.call(mapBookKeeping.mapContext, child, i); // We found a component instance ("production" !== "development" ? invariant( !mapResult.hasOwnProperty(name), 'ReactChildren.map(...): Encountered two children with the same key, ' + '`%s`. Children keys must be unique.', name ) : invariant(!mapResult.hasOwnProperty(name))); mapResult[name] = mappedChild;
}
/**
* Maps children that are typically specified as `props.children`. * * The provided mapFunction(child, key, index) will be called for each * leaf child. * * TODO: This may likely break any calls to `ReactChildren.map` that were * previously relying on the fact that we guarded against null children. * * @param {?*} children Children tree container. * @param {function(*, int)} mapFunction. * @param {*} mapContext Context for mapFunction. * @return {object} Object containing the ordered map of results. */
function mapChildren(children, func, context) {
if (children == null) { return children; } var mapResult = {}; var traverseContext = MapBookKeeping.getPooled(mapResult, func, context); traverseAllChildren(children, mapSingleChildIntoContext, traverseContext); MapBookKeeping.release(traverseContext); return mapResult;
}
var ReactChildren = {
forEach: forEachChildren, map: mapChildren
};
module.exports = ReactChildren;
},{“./PooledClass”:25,“./invariant”:125,“./traverseAllChildren”:146}],31:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactComponent */
“use strict”;
var ReactCurrentOwner = dereq(“./ReactCurrentOwner”); var ReactOwner = dereq(“./ReactOwner”); var ReactUpdates = dereq(“./ReactUpdates”);
var invariant = dereq(“./invariant”); var keyMirror = dereq(“./keyMirror”); var merge = dereq(“./merge”); var monitorCodeUse = dereq(“./monitorCodeUse”);
/**
* Every React component is in one of these life cycles. */
var ComponentLifeCycle = keyMirror({
/** * Mounted components have a DOM node representation and are capable of * receiving new props. */ MOUNTED: null, /** * Unmounted components are inactive and cannot receive new props. */ UNMOUNTED: null
});
/**
* Warn if there's no key explicitly set on dynamic arrays of children or * object keys are not valid. This allows us to keep track of children between * updates. */
var ownerHasExplicitKeyWarning = {}; var ownerHasPropertyWarning = {}; var ownerHasMonitoredObjectMap = {};
var NUMERIC_PROPERTY_REGEX = /^d+$/;
var injected = false;
/**
* Optionally injectable environment dependent cleanup hook. (server vs. * browser etc). Example: A browser system caches DOM nodes based on component * ID and must remove that cache entry when this instance is unmounted. * * @private */
var unmountIDFromEnvironment = null;
/**
* The "image" of a component tree, is the platform specific (typically * serialized) data that represents a tree of lower level UI building blocks. * On the web, this "image" is HTML markup which describes a construction of * low level `div` and `span` nodes. Other platforms may have different * encoding of this "image". This must be injected. * * @private */
var mountImageIntoNode = null;
/**
* Warn if the component doesn't have an explicit key assigned to it. * This component is in an array. The array could grow and shrink or be * reordered. All children that haven't already been validated are required to * have a "key" property assigned to it. * * @internal * @param {ReactComponent} component Component that requires a key. */
function validateExplicitKey(component) {
if (component.__keyValidated__ || component.props.key != null) { return; } component.__keyValidated__ = true; // We can't provide friendly warnings for top level components. if (!ReactCurrentOwner.current) { return; } // Name of the component whose render method tried to pass children. var currentName = ReactCurrentOwner.current.constructor.displayName; if (ownerHasExplicitKeyWarning.hasOwnProperty(currentName)) { return; } ownerHasExplicitKeyWarning[currentName] = true; var message = 'Each child in an array should have a unique "key" prop. ' + 'Check the render method of ' + currentName + '.'; var childOwnerName = null; if (!component.isOwnedBy(ReactCurrentOwner.current)) { // Name of the component that originally created this child. childOwnerName = component._owner && component._owner.constructor.displayName; // Usually the current owner is the offender, but if it accepts // children as a property, it may be the creator of the child that's // responsible for assigning it a key. message += ' It was passed a child from ' + childOwnerName + '.'; } message += ' See http://fb.me/react-warning-keys for more information.'; monitorCodeUse('react_key_warning', { component: currentName, componentOwner: childOwnerName }); console.warn(message);
}
/**
* Warn if the key is being defined as an object property but has an incorrect * value. * * @internal * @param {string} name Property name of the key. * @param {ReactComponent} component Component that requires a key. */
function validatePropertyKey(name) {
if (NUMERIC_PROPERTY_REGEX.test(name)) { // Name of the component whose render method tried to pass children. var currentName = ReactCurrentOwner.current.constructor.displayName; if (ownerHasPropertyWarning.hasOwnProperty(currentName)) { return; } ownerHasPropertyWarning[currentName] = true; monitorCodeUse('react_numeric_key_warning'); console.warn( 'Child objects should have non-numeric keys so ordering is preserved. ' + 'Check the render method of ' + currentName + '. ' + 'See http://fb.me/react-warning-keys for more information.' ); }
}
/**
* Log that we're using an object map. We're considering deprecating this * feature and replace it with proper Map and ImmutableMap data structures. * * @internal */
function monitorUseOfObjectMap() {
// Name of the component whose render method tried to pass children. // We only use this to avoid spewing the logs. We lose additional // owner stacks but hopefully one level is enough to trace the source. var currentName = (ReactCurrentOwner.current && ReactCurrentOwner.current.constructor.displayName) || ''; if (ownerHasMonitoredObjectMap.hasOwnProperty(currentName)) { return; } ownerHasMonitoredObjectMap[currentName] = true; monitorCodeUse('react_object_map_children');
}
/**
* Ensure that every component either is passed in a static location, in an * array with an explicit keys property defined, or in an object literal * with valid key property. * * @internal * @param {*} component Statically passed child of any type. * @return {boolean} */
function validateChildKeys(component) {
if (Array.isArray(component)) { for (var i = 0; i < component.length; i++) { var child = component[i]; if (ReactComponent.isValidComponent(child)) { validateExplicitKey(child); } } } else if (ReactComponent.isValidComponent(component)) { // This component was passed in a valid location. component.__keyValidated__ = true; } else if (component && typeof component === 'object') { monitorUseOfObjectMap(); for (var name in component) { validatePropertyKey(name, component); } }
}
/**
* Components are the basic units of composition in React. * * Every component accepts a set of keyed input parameters known as "props" that * are initialized by the constructor. Once a component is mounted, the props * can be mutated using `setProps` or `replaceProps`. * * Every component is capable of the following operations: * * `mountComponent` * Initializes the component, renders markup, and registers event listeners. * * `receiveComponent` * Updates the rendered DOM nodes to match the given component. * * `unmountComponent` * Releases any resources allocated by this component. * * Components can also be "owned" by other components. Being owned by another * component means being constructed by that component. This is different from * being the child of a component, which means having a DOM representation that * is a child of the DOM representation of that component. * * @class ReactComponent */
var ReactComponent = {
injection: { injectEnvironment: function(ReactComponentEnvironment) { ("production" !== "development" ? invariant( !injected, 'ReactComponent: injectEnvironment() can only be called once.' ) : invariant(!injected)); mountImageIntoNode = ReactComponentEnvironment.mountImageIntoNode; unmountIDFromEnvironment = ReactComponentEnvironment.unmountIDFromEnvironment; ReactComponent.BackendIDOperations = ReactComponentEnvironment.BackendIDOperations; ReactComponent.ReactReconcileTransaction = ReactComponentEnvironment.ReactReconcileTransaction; injected = true; } }, /** * @param {?object} object * @return {boolean} True if `object` is a valid component. * @final */ isValidComponent: function(object) { if (!object || !object.type || !object.type.prototype) { return false; } // This is the safer way of duck checking the type of instance this is. // The object can be a generic descriptor but the type property refers to // the constructor and it's prototype can be used to inspect the type that // will actually get mounted. var prototype = object.type.prototype; return ( typeof prototype.mountComponentIntoNode === 'function' && typeof prototype.receiveComponent === 'function' ); }, /** * @internal */ LifeCycle: ComponentLifeCycle, /** * Injected module that provides ability to mutate individual properties. * Injected into the base class because many different subclasses need access * to this. * * @internal */ BackendIDOperations: null, /** * React references `ReactReconcileTransaction` using this property in order * to allow dependency injection. * * @internal */ ReactReconcileTransaction: null, /** * Base functionality for every ReactComponent constructor. Mixed into the * `ReactComponent` prototype, but exposed statically for easy access. * * @lends {ReactComponent.prototype} */ Mixin: { /** * Checks whether or not this component is mounted. * * @return {boolean} True if mounted, false otherwise. * @final * @protected */ isMounted: function() { return this._lifeCycleState === ComponentLifeCycle.MOUNTED; }, /** * Sets a subset of the props. * * @param {object} partialProps Subset of the next props. * @param {?function} callback Called after props are updated. * @final * @public */ setProps: function(partialProps, callback) { // Merge with `_pendingProps` if it exists, otherwise with existing props. this.replaceProps( merge(this._pendingProps || this.props, partialProps), callback ); }, /** * Replaces all of the props. * * @param {object} props New props. * @param {?function} callback Called after props are updated. * @final * @public */ replaceProps: function(props, callback) { ("production" !== "development" ? invariant( this.isMounted(), 'replaceProps(...): Can only update a mounted component.' ) : invariant(this.isMounted())); ("production" !== "development" ? invariant( this._mountDepth === 0, 'replaceProps(...): You called `setProps` or `replaceProps` on a ' + 'component with a parent. This is an anti-pattern since props will ' + 'get reactively updated when rendered. Instead, change the owner\'s ' + '`render` method to pass the correct value as props to the component ' + 'where it is created.' ) : invariant(this._mountDepth === 0)); this._pendingProps = props; ReactUpdates.enqueueUpdate(this, callback); }, /** * Base constructor for all React components. * * Subclasses that override this method should make sure to invoke * `ReactComponent.Mixin.construct.call(this, ...)`. * * @param {?object} initialProps * @param {*} children * @internal */ construct: function(initialProps, children) { this.props = initialProps || {}; // Record the component responsible for creating this component. this._owner = ReactCurrentOwner.current; // All components start unmounted. this._lifeCycleState = ComponentLifeCycle.UNMOUNTED; this._pendingProps = null; this._pendingCallbacks = null; // Unlike _pendingProps and _pendingCallbacks, we won't use null to // indicate that nothing is pending because it's possible for a component // to have a null owner. Instead, an owner change is pending when // this._owner !== this._pendingOwner. this._pendingOwner = this._owner; // Children can be more than one argument var childrenLength = arguments.length - 1; if (childrenLength === 1) { if ("production" !== "development") { validateChildKeys(children); } this.props.children = children; } else if (childrenLength > 1) { var childArray = Array(childrenLength); for (var i = 0; i < childrenLength; i++) { if ("production" !== "development") { validateChildKeys(arguments[i + 1]); } childArray[i] = arguments[i + 1]; } this.props.children = childArray; } }, /** * Initializes the component, renders markup, and registers event listeners. * * NOTE: This does not insert any nodes into the DOM. * * Subclasses that override this method should make sure to invoke * `ReactComponent.Mixin.mountComponent.call(this, ...)`. * * @param {string} rootID DOM ID of the root node. * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction * @param {number} mountDepth number of components in the owner hierarchy. * @return {?string} Rendered markup to be inserted into the DOM. * @internal */ mountComponent: function(rootID, transaction, mountDepth) { ("production" !== "development" ? invariant( !this.isMounted(), 'mountComponent(%s, ...): Can only mount an unmounted component. ' + 'Make sure to avoid storing components between renders or reusing a ' + 'single component instance in multiple places.', rootID ) : invariant(!this.isMounted())); var props = this.props; if (props.ref != null) { ReactOwner.addComponentAsRefTo(this, props.ref, this._owner); } this._rootNodeID = rootID; this._lifeCycleState = ComponentLifeCycle.MOUNTED; this._mountDepth = mountDepth; // Effectively: return ''; }, /** * Releases any resources allocated by `mountComponent`. * * NOTE: This does not remove any nodes from the DOM. * * Subclasses that override this method should make sure to invoke * `ReactComponent.Mixin.unmountComponent.call(this)`. * * @internal */ unmountComponent: function() { ("production" !== "development" ? invariant( this.isMounted(), 'unmountComponent(): Can only unmount a mounted component.' ) : invariant(this.isMounted())); var props = this.props; if (props.ref != null) { ReactOwner.removeComponentAsRefFrom(this, props.ref, this._owner); } unmountIDFromEnvironment(this._rootNodeID); this._rootNodeID = null; this._lifeCycleState = ComponentLifeCycle.UNMOUNTED; }, /** * Given a new instance of this component, updates the rendered DOM nodes * as if that instance was rendered instead. * * Subclasses that override this method should make sure to invoke * `ReactComponent.Mixin.receiveComponent.call(this, ...)`. * * @param {object} nextComponent Next set of properties. * @param {ReactReconcileTransaction} transaction * @internal */ receiveComponent: function(nextComponent, transaction) { ("production" !== "development" ? invariant( this.isMounted(), 'receiveComponent(...): Can only update a mounted component.' ) : invariant(this.isMounted())); this._pendingOwner = nextComponent._owner; this._pendingProps = nextComponent.props; this._performUpdateIfNecessary(transaction); }, /** * Call `_performUpdateIfNecessary` within a new transaction. * * @internal */ performUpdateIfNecessary: function() { var transaction = ReactComponent.ReactReconcileTransaction.getPooled(); transaction.perform(this._performUpdateIfNecessary, this, transaction); ReactComponent.ReactReconcileTransaction.release(transaction); }, /** * If `_pendingProps` is set, update the component. * * @param {ReactReconcileTransaction} transaction * @internal */ _performUpdateIfNecessary: function(transaction) { if (this._pendingProps == null) { return; } var prevProps = this.props; var prevOwner = this._owner; this.props = this._pendingProps; this._owner = this._pendingOwner; this._pendingProps = null; this.updateComponent(transaction, prevProps, prevOwner); }, /** * Updates the component's currently mounted representation. * * @param {ReactReconcileTransaction} transaction * @param {object} prevProps * @internal */ updateComponent: function(transaction, prevProps, prevOwner) { var props = this.props; // If either the owner or a `ref` has changed, make sure the newest owner // has stored a reference to `this`, and the previous owner (if different) // has forgotten the reference to `this`. if (this._owner !== prevOwner || props.ref !== prevProps.ref) { if (prevProps.ref != null) { ReactOwner.removeComponentAsRefFrom( this, prevProps.ref, prevOwner ); } // Correct, even if the owner is the same, and only the ref has changed. if (props.ref != null) { ReactOwner.addComponentAsRefTo(this, props.ref, this._owner); } } }, /** * Mounts this component and inserts it into the DOM. * * @param {string} rootID DOM ID of the root node. * @param {DOMElement} container DOM element to mount into. * @param {boolean} shouldReuseMarkup If true, do not insert markup * @final * @internal * @see {ReactMount.renderComponent} */ mountComponentIntoNode: function(rootID, container, shouldReuseMarkup) { var transaction = ReactComponent.ReactReconcileTransaction.getPooled(); transaction.perform( this._mountComponentIntoNode, this, rootID, container, transaction, shouldReuseMarkup ); ReactComponent.ReactReconcileTransaction.release(transaction); }, /** * @param {string} rootID DOM ID of the root node. * @param {DOMElement} container DOM element to mount into. * @param {ReactReconcileTransaction} transaction * @param {boolean} shouldReuseMarkup If true, do not insert markup * @final * @private */ _mountComponentIntoNode: function( rootID, container, transaction, shouldReuseMarkup) { var markup = this.mountComponent(rootID, transaction, 0); mountImageIntoNode(markup, container, shouldReuseMarkup); }, /** * Checks if this component is owned by the supplied `owner` component. * * @param {ReactComponent} owner Component to check. * @return {boolean} True if `owners` owns this component. * @final * @internal */ isOwnedBy: function(owner) { return this._owner === owner; }, /** * Gets another component, that shares the same owner as this one, by ref. * * @param {string} ref of a sibling Component. * @return {?ReactComponent} the actual sibling Component. * @final * @internal */ getSiblingByRef: function(ref) { var owner = this._owner; if (!owner || !owner.refs) { return null; } return owner.refs[ref]; } }
};
module.exports = ReactComponent;
},{“./ReactCurrentOwner”:35,“./ReactOwner”:64,“./ReactUpdates”:81,“./invariant”:125,“./keyMirror”:131,“./merge”:134,“./monitorCodeUse”:138}],32:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactComponentBrowserEnvironment */
/*jslint evil: true */
“use strict”;
var ReactDOMIDOperations = dereq(“./ReactDOMIDOperations”); var ReactMarkupChecksum = dereq(“./ReactMarkupChecksum”); var ReactMount = dereq(“./ReactMount”); var ReactPerf = dereq(“./ReactPerf”); var ReactReconcileTransaction = dereq(“./ReactReconcileTransaction”);
var getReactRootElementInContainer = dereq(“./getReactRootElementInContainer”); var invariant = dereq(“./invariant”);
var ELEMENT_NODE_TYPE = 1; var DOC_NODE_TYPE = 9;
/**
* Abstracts away all functionality of `ReactComponent` requires knowledge of * the browser context. */
var ReactComponentBrowserEnvironment = {
ReactReconcileTransaction: ReactReconcileTransaction, BackendIDOperations: ReactDOMIDOperations, /** * If a particular environment requires that some resources be cleaned up, * specify this in the injected Mixin. In the DOM, we would likely want to * purge any cached node ID lookups. * * @private */ unmountIDFromEnvironment: function(rootNodeID) { ReactMount.purgeID(rootNodeID); }, /** * @param {string} markup Markup string to place into the DOM Element. * @param {DOMElement} container DOM Element to insert markup into. * @param {boolean} shouldReuseMarkup Should reuse the existing markup in the * container if possible. */ mountImageIntoNode: ReactPerf.measure( 'ReactComponentBrowserEnvironment', 'mountImageIntoNode', function(markup, container, shouldReuseMarkup) { ("production" !== "development" ? invariant( container && ( container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE ), 'mountComponentIntoNode(...): Target container is not valid.' ) : invariant(container && ( container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE ))); if (shouldReuseMarkup) { if (ReactMarkupChecksum.canReuseMarkup( markup, getReactRootElementInContainer(container))) { return; } else { ("production" !== "development" ? invariant( container.nodeType !== DOC_NODE_TYPE, 'You\'re trying to render a component to the document using ' + 'server rendering but the checksum was invalid. This usually ' + 'means you rendered a different component type or props on ' + 'the client from the one on the server, or your render() ' + 'methods are impure. React cannot handle this case due to ' + 'cross-browser quirks by rendering at the document root. You ' + 'should look for environment dependent code in your components ' + 'and ensure the props are the same client and server side.' ) : invariant(container.nodeType !== DOC_NODE_TYPE)); if ("production" !== "development") { console.warn( 'React attempted to use reuse markup in a container but the ' + 'checksum was invalid. This generally means that you are ' + 'using server rendering and the markup generated on the ' + 'server was not what the client was expecting. React injected' + 'new markup to compensate which works but you have lost many ' + 'of the benefits of server rendering. Instead, figure out ' + 'why the markup being generated is different on the client ' + 'or server.' ); } } } ("production" !== "development" ? invariant( container.nodeType !== DOC_NODE_TYPE, 'You\'re trying to render a component to the document but ' + 'you didn\'t use server rendering. We can\'t do this ' + 'without using server rendering due to cross-browser quirks. ' + 'See renderComponentToString() for server rendering.' ) : invariant(container.nodeType !== DOC_NODE_TYPE)); container.innerHTML = markup; } )
};
module.exports = ReactComponentBrowserEnvironment;
},{“./ReactDOMIDOperations”:40,“./ReactMarkupChecksum”:59,“./ReactMount”:60,“./ReactPerf”:65,“./ReactReconcileTransaction”:71,“./getReactRootElementInContainer”:120,“./invariant”:125}],33:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactCompositeComponent */
“use strict”;
var ReactComponent = dereq(“./ReactComponent”); var ReactContext = dereq(“./ReactContext”); var ReactCurrentOwner = dereq(“./ReactCurrentOwner”); var ReactErrorUtils = dereq(“./ReactErrorUtils”); var ReactOwner = dereq(“./ReactOwner”); var ReactPerf = dereq(“./ReactPerf”); var ReactPropTransferer = dereq(“./ReactPropTransferer”); var ReactPropTypeLocations = dereq(“./ReactPropTypeLocations”); var ReactPropTypeLocationNames = dereq(“./ReactPropTypeLocationNames”); var ReactUpdates = dereq(“./ReactUpdates”);
var instantiateReactComponent = dereq(“./instantiateReactComponent”); var invariant = dereq(“./invariant”); var keyMirror = dereq(“./keyMirror”); var merge = dereq(“./merge”); var mixInto = dereq(“./mixInto”); var monitorCodeUse = dereq(“./monitorCodeUse”); var objMap = dereq(“./objMap”); var shouldUpdateReactComponent = dereq(“./shouldUpdateReactComponent”); var warning = dereq(“./warning”);
/**
* Policies that describe methods in `ReactCompositeComponentInterface`. */
var SpecPolicy = keyMirror({
/** * These methods may be defined only once by the class specification or mixin. */ DEFINE_ONCE: null, /** * These methods may be defined by both the class specification and mixins. * Subsequent definitions will be chained. These methods must return void. */ DEFINE_MANY: null, /** * These methods are overriding the base ReactCompositeComponent class. */ OVERRIDE_BASE: null, /** * These methods are similar to DEFINE_MANY, except we assume they return * objects. We try to merge the keys of the return values of all the mixed in * functions. If there is a key conflict we throw. */ DEFINE_MANY_MERGED: null
});
var injectedMixins = [];
/**
* Composite components are higher-level components that compose other composite * or native components. * * To create a new type of `ReactCompositeComponent`, pass a specification of * your new class to `React.createClass`. The only requirement of your class * specification is that you implement a `render` method. * * var MyComponent = React.createClass({ * render: function() { * return <div>Hello World</div>; * } * }); * * The class specification supports a specific protocol of methods that have * special meaning (e.g. `render`). See `ReactCompositeComponentInterface` for * more the comprehensive protocol. Any other properties and methods in the * class specification will available on the prototype. * * @interface ReactCompositeComponentInterface * @internal */
var ReactCompositeComponentInterface = {
/** * An array of Mixin objects to include when defining your component. * * @type {array} * @optional */ mixins: SpecPolicy.DEFINE_MANY, /** * An object containing properties and methods that should be defined on * the component's constructor instead of its prototype (static methods). * * @type {object} * @optional */ statics: SpecPolicy.DEFINE_MANY, /** * Definition of prop types for this component. * * @type {object} * @optional */ propTypes: SpecPolicy.DEFINE_MANY, /** * Definition of context types for this component. * * @type {object} * @optional */ contextTypes: SpecPolicy.DEFINE_MANY, /** * Definition of context types this component sets for its children. * * @type {object} * @optional */ childContextTypes: SpecPolicy.DEFINE_MANY, // ==== Definition methods ==== /** * Invoked when the component is mounted. Values in the mapping will be set on * `this.props` if that prop is not specified (i.e. using an `in` check). * * This method is invoked before `getInitialState` and therefore cannot rely * on `this.state` or use `this.setState`. * * @return {object} * @optional */ getDefaultProps: SpecPolicy.DEFINE_MANY_MERGED, /** * Invoked once before the component is mounted. The return value will be used * as the initial value of `this.state`. * * getInitialState: function() { * return { * isOn: false, * fooBaz: new BazFoo() * } * } * * @return {object} * @optional */ getInitialState: SpecPolicy.DEFINE_MANY_MERGED, /** * @return {object} * @optional */ getChildContext: SpecPolicy.DEFINE_MANY_MERGED, /** * Uses props from `this.props` and state from `this.state` to render the * structure of the component. * * No guarantees are made about when or how often this method is invoked, so * it must not have side effects. * * render: function() { * var name = this.props.name; * return <div>Hello, {name}!</div>; * } * * @return {ReactComponent} * @nosideeffects * @required */ render: SpecPolicy.DEFINE_ONCE, // ==== Delegate methods ==== /** * Invoked when the component is initially created and about to be mounted. * This may have side effects, but any external subscriptions or data created * by this method must be cleaned up in `componentWillUnmount`. * * @optional */ componentWillMount: SpecPolicy.DEFINE_MANY, /** * Invoked when the component has been mounted and has a DOM representation. * However, there is no guarantee that the DOM node is in the document. * * Use this as an opportunity to operate on the DOM when the component has * been mounted (initialized and rendered) for the first time. * * @param {DOMElement} rootNode DOM element representing the component. * @optional */ componentDidMount: SpecPolicy.DEFINE_MANY, /** * Invoked before the component receives new props. * * Use this as an opportunity to react to a prop transition by updating the * state using `this.setState`. Current props are accessed via `this.props`. * * componentWillReceiveProps: function(nextProps, nextContext) { * this.setState({ * likesIncreasing: nextProps.likeCount > this.props.likeCount * }); * } * * NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop * transition may cause a state change, but the opposite is not true. If you * need it, you are probably looking for `componentWillUpdate`. * * @param {object} nextProps * @optional */ componentWillReceiveProps: SpecPolicy.DEFINE_MANY, /** * Invoked while deciding if the component should be updated as a result of * receiving new props, state and/or context. * * Use this as an opportunity to `return false` when you're certain that the * transition to the new props/state/context will not require a component * update. * * shouldComponentUpdate: function(nextProps, nextState, nextContext) { * return !equal(nextProps, this.props) || * !equal(nextState, this.state) || * !equal(nextContext, this.context); * } * * @param {object} nextProps * @param {?object} nextState * @param {?object} nextContext * @return {boolean} True if the component should update. * @optional */ shouldComponentUpdate: SpecPolicy.DEFINE_ONCE, /** * Invoked when the component is about to update due to a transition from * `this.props`, `this.state` and `this.context` to `nextProps`, `nextState` * and `nextContext`. * * Use this as an opportunity to perform preparation before an update occurs. * * NOTE: You **cannot** use `this.setState()` in this method. * * @param {object} nextProps * @param {?object} nextState * @param {?object} nextContext * @param {ReactReconcileTransaction} transaction * @optional */ componentWillUpdate: SpecPolicy.DEFINE_MANY, /** * Invoked when the component's DOM representation has been updated. * * Use this as an opportunity to operate on the DOM when the component has * been updated. * * @param {object} prevProps * @param {?object} prevState * @param {?object} prevContext * @param {DOMElement} rootNode DOM element representing the component. * @optional */ componentDidUpdate: SpecPolicy.DEFINE_MANY, /** * Invoked when the component is about to be removed from its parent and have * its DOM representation destroyed. * * Use this as an opportunity to deallocate any external resources. * * NOTE: There is no `componentDidUnmount` since your component will have been * destroyed by that point. * * @optional */ componentWillUnmount: SpecPolicy.DEFINE_MANY, // ==== Advanced methods ==== /** * Updates the component's currently mounted DOM representation. * * By default, this implements React's rendering and reconciliation algorithm. * Sophisticated clients may wish to override this. * * @param {ReactReconcileTransaction} transaction * @internal * @overridable */ updateComponent: SpecPolicy.OVERRIDE_BASE
};
/**
* Mapping from class specification keys to special processing functions. * * Although these are declared like instance properties in the specification * when defining classes using `React.createClass`, they are actually static * and are accessible on the constructor instead of the prototype. Despite * being static, they must be defined outside of the "statics" key under * which all other static methods are defined. */
var RESERVED_SPEC_KEYS = {
displayName: function(ConvenienceConstructor, displayName) { ConvenienceConstructor.componentConstructor.displayName = displayName; }, mixins: function(ConvenienceConstructor, mixins) { if (mixins) { for (var i = 0; i < mixins.length; i++) { mixSpecIntoComponent(ConvenienceConstructor, mixins[i]); } } }, childContextTypes: function(ConvenienceConstructor, childContextTypes) { var Constructor = ConvenienceConstructor.componentConstructor; validateTypeDef( Constructor, childContextTypes, ReactPropTypeLocations.childContext ); Constructor.childContextTypes = merge( Constructor.childContextTypes, childContextTypes ); }, contextTypes: function(ConvenienceConstructor, contextTypes) { var Constructor = ConvenienceConstructor.componentConstructor; validateTypeDef( Constructor, contextTypes, ReactPropTypeLocations.context ); Constructor.contextTypes = merge(Constructor.contextTypes, contextTypes); }, propTypes: function(ConvenienceConstructor, propTypes) { var Constructor = ConvenienceConstructor.componentConstructor; validateTypeDef( Constructor, propTypes, ReactPropTypeLocations.prop ); Constructor.propTypes = merge(Constructor.propTypes, propTypes); }, statics: function(ConvenienceConstructor, statics) { mixStaticSpecIntoComponent(ConvenienceConstructor, statics); }
};
function validateTypeDef(Constructor, typeDef, location) {
for (var propName in typeDef) { if (typeDef.hasOwnProperty(propName)) { ("production" !== "development" ? invariant( typeof typeDef[propName] == 'function', '%s: %s type `%s` is invalid; it must be a function, usually from ' + 'React.PropTypes.', Constructor.displayName || 'ReactCompositeComponent', ReactPropTypeLocationNames[location], propName ) : invariant(typeof typeDef[propName] == 'function')); } }
}
function validateMethodOverride(proto, name) {
var specPolicy = ReactCompositeComponentInterface[name]; // Disallow overriding of base class methods unless explicitly allowed. if (ReactCompositeComponentMixin.hasOwnProperty(name)) { ("production" !== "development" ? invariant( specPolicy === SpecPolicy.OVERRIDE_BASE, 'ReactCompositeComponentInterface: You are attempting to override ' + '`%s` from your class specification. Ensure that your method names ' + 'do not overlap with React methods.', name ) : invariant(specPolicy === SpecPolicy.OVERRIDE_BASE)); } // Disallow defining methods more than once unless explicitly allowed. if (proto.hasOwnProperty(name)) { ("production" !== "development" ? invariant( specPolicy === SpecPolicy.DEFINE_MANY || specPolicy === SpecPolicy.DEFINE_MANY_MERGED, 'ReactCompositeComponentInterface: You are attempting to define ' + '`%s` on your component more than once. This conflict may be due ' + 'to a mixin.', name ) : invariant(specPolicy === SpecPolicy.DEFINE_MANY || specPolicy === SpecPolicy.DEFINE_MANY_MERGED)); }
}
function validateLifeCycleOnReplaceState(instance) {
var compositeLifeCycleState = instance._compositeLifeCycleState; ("production" !== "development" ? invariant( instance.isMounted() || compositeLifeCycleState === CompositeLifeCycle.MOUNTING, 'replaceState(...): Can only update a mounted or mounting component.' ) : invariant(instance.isMounted() || compositeLifeCycleState === CompositeLifeCycle.MOUNTING)); ("production" !== "development" ? invariant(compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE, 'replaceState(...): Cannot update during an existing state transition ' + '(such as within `render`). This could potentially cause an infinite ' + 'loop so it is forbidden.' ) : invariant(compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE)); ("production" !== "development" ? invariant(compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING, 'replaceState(...): Cannot update while unmounting component. This ' + 'usually means you called setState() on an unmounted component.' ) : invariant(compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING));
}
/**
* Custom version of `mixInto` which handles policy validation and reserved * specification keys when building `ReactCompositeComponent` classses. */
function mixSpecIntoComponent(ConvenienceConstructor, spec) {
("production" !== "development" ? invariant( !isValidClass(spec), 'ReactCompositeComponent: You\'re attempting to ' + 'use a component class as a mixin. Instead, just use a regular object.' ) : invariant(!isValidClass(spec))); ("production" !== "development" ? invariant( !ReactComponent.isValidComponent(spec), 'ReactCompositeComponent: You\'re attempting to ' + 'use a component as a mixin. Instead, just use a regular object.' ) : invariant(!ReactComponent.isValidComponent(spec))); var Constructor = ConvenienceConstructor.componentConstructor; var proto = Constructor.prototype; for (var name in spec) { var property = spec[name]; if (!spec.hasOwnProperty(name)) { continue; } validateMethodOverride(proto, name); if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) { RESERVED_SPEC_KEYS[name](ConvenienceConstructor, property); } else { // Setup methods on prototype: // The following member methods should not be automatically bound: // 1. Expected ReactCompositeComponent methods (in the "interface"). // 2. Overridden methods (that were mixed in). var isCompositeComponentMethod = name in ReactCompositeComponentInterface; var isInherited = name in proto; var markedDontBind = property && property.__reactDontBind; var isFunction = typeof property === 'function'; var shouldAutoBind = isFunction && !isCompositeComponentMethod && !isInherited && !markedDontBind; if (shouldAutoBind) { if (!proto.__reactAutoBindMap) { proto.__reactAutoBindMap = {}; } proto.__reactAutoBindMap[name] = property; proto[name] = property; } else { if (isInherited) { // For methods which are defined more than once, call the existing // methods before calling the new property. if (ReactCompositeComponentInterface[name] === SpecPolicy.DEFINE_MANY_MERGED) { proto[name] = createMergedResultFunction(proto[name], property); } else { proto[name] = createChainedFunction(proto[name], property); } } else { proto[name] = property; } } } }
}
function mixStaticSpecIntoComponent(ConvenienceConstructor, statics) {
if (!statics) { return; } for (var name in statics) { var property = statics[name]; if (!statics.hasOwnProperty(name)) { return; } var isInherited = name in ConvenienceConstructor; var result = property; if (isInherited) { var existingProperty = ConvenienceConstructor[name]; var existingType = typeof existingProperty; var propertyType = typeof property; ("production" !== "development" ? invariant( existingType === 'function' && propertyType === 'function', 'ReactCompositeComponent: You are attempting to define ' + '`%s` on your component more than once, but that is only supported ' + 'for functions, which are chained together. This conflict may be ' + 'due to a mixin.', name ) : invariant(existingType === 'function' && propertyType === 'function')); result = createChainedFunction(existingProperty, property); } ConvenienceConstructor[name] = result; ConvenienceConstructor.componentConstructor[name] = result; }
}
/**
* Merge two objects, but throw if both contain the same key. * * @param {object} one The first object, which is mutated. * @param {object} two The second object * @return {object} one after it has been mutated to contain everything in two. */
function mergeObjectsWithNoDuplicateKeys(one, two) {
("production" !== "development" ? invariant( one && two && typeof one === 'object' && typeof two === 'object', 'mergeObjectsWithNoDuplicateKeys(): Cannot merge non-objects' ) : invariant(one && two && typeof one === 'object' && typeof two === 'object')); objMap(two, function(value, key) { ("production" !== "development" ? invariant( one[key] === undefined, 'mergeObjectsWithNoDuplicateKeys(): ' + 'Tried to merge two objects with the same key: %s', key ) : invariant(one[key] === undefined)); one[key] = value; }); return one;
}
/**
* Creates a function that invokes two functions and merges their return values. * * @param {function} one Function to invoke first. * @param {function} two Function to invoke second. * @return {function} Function that invokes the two argument functions. * @private */
function createMergedResultFunction(one, two) {
return function mergedResult() { var a = one.apply(this, arguments); var b = two.apply(this, arguments); if (a == null) { return b; } else if (b == null) { return a; } return mergeObjectsWithNoDuplicateKeys(a, b); };
}
/**
* Creates a function that invokes two functions and ignores their return vales. * * @param {function} one Function to invoke first. * @param {function} two Function to invoke second. * @return {function} Function that invokes the two argument functions. * @private */
function createChainedFunction(one, two) {
return function chainedFunction() { one.apply(this, arguments); two.apply(this, arguments); };
}
if (“production” !== “development”) {
var unmountedPropertyWhitelist = { constructor: true, construct: true, isOwnedBy: true, // should be deprecated but can have code mod (internal) type: true, props: true, // currently private but belong on the descriptor and are valid for use // inside the framework: __keyValidated__: true, _owner: true, _currentContext: true }; var componentInstanceProperties = { __keyValidated__: true, __keySetters: true, _compositeLifeCycleState: true, _currentContext: true, _defaultProps: true, _instance: true, _lifeCycleState: true, _mountDepth: true, _owner: true, _pendingCallbacks: true, _pendingContext: true, _pendingForceUpdate: true, _pendingOwner: true, _pendingProps: true, _pendingState: true, _renderedComponent: true, _rootNodeID: true, context: true, props: true, refs: true, state: true, // These are known instance properties coming from other sources _pendingQueries: true, _queryPropListeners: true, queryParams: true }; var hasWarnedOnComponentType = {}; var warningStackCounter = 0; var issueMembraneWarning = function(instance, key) { var isWhitelisted = unmountedPropertyWhitelist.hasOwnProperty(key); if (warningStackCounter > 0 || isWhitelisted) { return; } var name = instance.constructor.displayName || 'Unknown'; var owner = ReactCurrentOwner.current; var ownerName = (owner && owner.constructor.displayName) || 'Unknown'; var warningKey = key + '|' + name + '|' + ownerName; if (hasWarnedOnComponentType.hasOwnProperty(warningKey)) { // We have already warned for this combination. Skip it this time. return; } hasWarnedOnComponentType[warningKey] = true; var context = owner ? ' in ' + ownerName + '.' : ' at the top level.'; var staticMethodExample = '<' + name + ' />.type.' + key + '(...)'; monitorCodeUse('react_descriptor_property_access', { component: name }); console.warn( 'Invalid access to component property "' + key + '" on ' + name + context + ' See http://fb.me/react-warning-descriptors .' + ' Use a static method instead: ' + staticMethodExample ); }; var wrapInMembraneFunction = function(fn, thisBinding) { if (fn.__reactMembraneFunction && fn.__reactMembraneSelf === thisBinding) { return fn.__reactMembraneFunction; } return fn.__reactMembraneFunction = function() { /** * By getting this function, you've already received a warning. The * internals of this function will likely cause more warnings. To avoid * Spamming too much we disable any warning triggered inside of this * stack. */ warningStackCounter++; try { // If the this binding is unchanged, we defer to the real component. // This is important to keep some referential integrity in the // internals. E.g. owner equality check. var self = this === thisBinding ? this.__realComponentInstance : this; return fn.apply(self, arguments); } finally { warningStackCounter--; } }; }; var defineMembraneProperty = function(membrane, prototype, key) { Object.defineProperty(membrane, key, { configurable: false, enumerable: true, get: function() { if (this === membrane) { // We're allowed to access the prototype directly. return prototype[key]; } issueMembraneWarning(this, key); var realValue = this.__realComponentInstance[key]; // If the real value is a function, we need to provide a wrapper that // disables nested warnings. The properties type and constructors are // expected to the be constructors and therefore is often use with an // equality check and we shouldn't try to rebind those. if (typeof realValue === 'function' && key !== 'type' && key !== 'constructor') { return wrapInMembraneFunction(realValue, this); } return realValue; }, set: function(value) { if (this === membrane) { // We're allowed to set a value on the prototype directly. prototype[key] = value; return; } issueMembraneWarning(this, key); this.__realComponentInstance[key] = value; } }); }; /** * Creates a membrane prototype which wraps the original prototype. If any * property is accessed in an unmounted state, a warning is issued. * * @param {object} prototype Original prototype. * @return {object} The membrane prototype. * @private */ var createMountWarningMembrane = function(prototype) { var membrane = {}; var key; for (key in prototype) { defineMembraneProperty(membrane, prototype, key); } // These are properties that goes into the instance but not the prototype. // We can create the membrane on the prototype even though this will // result in a faulty hasOwnProperty check it's better perf. for (key in componentInstanceProperties) { if (componentInstanceProperties.hasOwnProperty(key) && !(key in prototype)) { defineMembraneProperty(membrane, prototype, key); } } return membrane; }; /** * Creates a membrane constructor which wraps the component that gets mounted. * * @param {function} constructor Original constructor. * @return {function} The membrane constructor. * @private */ var createDescriptorProxy = function(constructor) { try { var ProxyConstructor = function() { this.__realComponentInstance = new constructor(); // We can only safely pass through known instance variables. Unknown // expandos are not safe. Use the real mounted instance to avoid this // problem if it blows something up. Object.freeze(this); }; ProxyConstructor.prototype = createMountWarningMembrane( constructor.prototype ); return ProxyConstructor; } catch(x) { // In IE8 define property will fail on non-DOM objects. If anything in // the membrane creation fails, we'll bail out and just use the plain // constructor without warnings. return constructor; } };
}
/**
* `ReactCompositeComponent` maintains an auxiliary life cycle state in * `this._compositeLifeCycleState` (which can be null). * * This is different from the life cycle state maintained by `ReactComponent` in * `this._lifeCycleState`. The following diagram shows how the states overlap in * time. There are times when the CompositeLifeCycle is null - at those times it * is only meaningful to look at ComponentLifeCycle alone. * * Top Row: ReactComponent.ComponentLifeCycle * Low Row: ReactComponent.CompositeLifeCycle * * +-------+------------------------------------------------------+--------+ * | UN | MOUNTED | UN | * |MOUNTED| | MOUNTED| * +-------+------------------------------------------------------+--------+ * | ^--------+ +------+ +------+ +------+ +--------^ | * | | | | | | | | | | | | * | 0--|MOUNTING|-0-|RECEIV|-0-|RECEIV|-0-|RECEIV|-0-| UN |--->0 | * | | | |PROPS | | PROPS| | STATE| |MOUNTING| | * | | | | | | | | | | | | * | | | | | | | | | | | | * | +--------+ +------+ +------+ +------+ +--------+ | * | | | | * +-------+------------------------------------------------------+--------+ */
var CompositeLifeCycle = keyMirror({
/** * Components in the process of being mounted respond to state changes * differently. */ MOUNTING: null, /** * Components in the process of being unmounted are guarded against state * changes. */ UNMOUNTING: null, /** * Components that are mounted and receiving new props respond to state * changes differently. */ RECEIVING_PROPS: null, /** * Components that are mounted and receiving new state are guarded against * additional state changes. */ RECEIVING_STATE: null
});
/**
* @lends {ReactCompositeComponent.prototype} */
var ReactCompositeComponentMixin = {
/** * Base constructor for all composite component. * * @param {?object} initialProps * @param {*} children * @final * @internal */ construct: function(initialProps, children) { // Children can be either an array or more than one argument ReactComponent.Mixin.construct.apply(this, arguments); ReactOwner.Mixin.construct.apply(this, arguments); this.state = null; this._pendingState = null; this.context = null; this._currentContext = ReactContext.current; this._pendingContext = null; // The descriptor that was used to instantiate this component. Will be // set by the instantiator instead of the constructor since this // constructor is currently used by both instances and descriptors. this._descriptor = null; this._compositeLifeCycleState = null; }, /** * Components in the intermediate state now has cyclic references. To avoid * breaking JSON serialization we expose a custom JSON format. * @return {object} JSON compatible representation. * @internal * @final */ toJSON: function() { return { type: this.type, props: this.props }; }, /** * Checks whether or not this composite component is mounted. * @return {boolean} True if mounted, false otherwise. * @protected * @final */ isMounted: function() { return ReactComponent.Mixin.isMounted.call(this) && this._compositeLifeCycleState !== CompositeLifeCycle.MOUNTING; }, /** * Initializes the component, renders markup, and registers event listeners. * * @param {string} rootID DOM ID of the root node. * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction * @param {number} mountDepth number of components in the owner hierarchy * @return {?string} Rendered markup to be inserted into the DOM. * @final * @internal */ mountComponent: ReactPerf.measure( 'ReactCompositeComponent', 'mountComponent', function(rootID, transaction, mountDepth) { ReactComponent.Mixin.mountComponent.call( this, rootID, transaction, mountDepth ); this._compositeLifeCycleState = CompositeLifeCycle.MOUNTING; this.context = this._processContext(this._currentContext); this._defaultProps = this.getDefaultProps ? this.getDefaultProps() : null; this.props = this._processProps(this.props); if (this.__reactAutoBindMap) { this._bindAutoBindMethods(); } this.state = this.getInitialState ? this.getInitialState() : null; ("production" !== "development" ? invariant( typeof this.state === 'object' && !Array.isArray(this.state), '%s.getInitialState(): must return an object or null', this.constructor.displayName || 'ReactCompositeComponent' ) : invariant(typeof this.state === 'object' && !Array.isArray(this.state))); this._pendingState = null; this._pendingForceUpdate = false; if (this.componentWillMount) { this.componentWillMount(); // When mounting, calls to `setState` by `componentWillMount` will set // `this._pendingState` without triggering a re-render. if (this._pendingState) { this.state = this._pendingState; this._pendingState = null; } } this._renderedComponent = instantiateReactComponent( this._renderValidatedComponent() ); // Done with mounting, `setState` will now trigger UI changes. this._compositeLifeCycleState = null; var markup = this._renderedComponent.mountComponent( rootID, transaction, mountDepth + 1 ); if (this.componentDidMount) { transaction.getReactMountReady().enqueue(this, this.componentDidMount); } return markup; } ), /** * Releases any resources allocated by `mountComponent`. * * @final * @internal */ unmountComponent: function() { this._compositeLifeCycleState = CompositeLifeCycle.UNMOUNTING; if (this.componentWillUnmount) { this.componentWillUnmount(); } this._compositeLifeCycleState = null; this._defaultProps = null; this._renderedComponent.unmountComponent(); this._renderedComponent = null; ReactComponent.Mixin.unmountComponent.call(this); // Some existing components rely on this.props even after they've been // destroyed (in event handlers). // TODO: this.props = null; // TODO: this.state = null; }, /** * Sets a subset of the state. Always use this or `replaceState` to mutate * state. You should treat `this.state` as immutable. * * There is no guarantee that `this.state` will be immediately updated, so * accessing `this.state` after calling this method may return the old value. * * There is no guarantee that calls to `setState` will run synchronously, * as they may eventually be batched together. You can provide an optional * callback that will be executed when the call to setState is actually * completed. * * @param {object} partialState Next partial state to be merged with state. * @param {?function} callback Called after state is updated. * @final * @protected */ setState: function(partialState, callback) { ("production" !== "development" ? invariant( typeof partialState === 'object' || partialState == null, 'setState(...): takes an object of state variables to update.' ) : invariant(typeof partialState === 'object' || partialState == null)); if ("production" !== "development") { ("production" !== "development" ? warning( partialState != null, 'setState(...): You passed an undefined or null state object; ' + 'instead, use forceUpdate().' ) : null); } // Merge with `_pendingState` if it exists, otherwise with existing state. this.replaceState( merge(this._pendingState || this.state, partialState), callback ); }, /** * Replaces all of the state. Always use this or `setState` to mutate state. * You should treat `this.state` as immutable. * * There is no guarantee that `this.state` will be immediately updated, so * accessing `this.state` after calling this method may return the old value. * * @param {object} completeState Next state. * @param {?function} callback Called after state is updated. * @final * @protected */ replaceState: function(completeState, callback) { validateLifeCycleOnReplaceState(this); this._pendingState = completeState; ReactUpdates.enqueueUpdate(this, callback); }, /** * Filters the context object to only contain keys specified in * `contextTypes`, and asserts that they are valid. * * @param {object} context * @return {?object} * @private */ _processContext: function(context) { var maskedContext = null; var contextTypes = this.constructor.contextTypes; if (contextTypes) { maskedContext = {}; for (var contextName in contextTypes) { maskedContext[contextName] = context[contextName]; } if ("production" !== "development") { this._checkPropTypes( contextTypes, maskedContext, ReactPropTypeLocations.context ); } } return maskedContext; }, /** * @param {object} currentContext * @return {object} * @private */ _processChildContext: function(currentContext) { var childContext = this.getChildContext && this.getChildContext(); var displayName = this.constructor.displayName || 'ReactCompositeComponent'; if (childContext) { ("production" !== "development" ? invariant( typeof this.constructor.childContextTypes === 'object', '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', displayName ) : invariant(typeof this.constructor.childContextTypes === 'object')); if ("production" !== "development") { this._checkPropTypes( this.constructor.childContextTypes, childContext, ReactPropTypeLocations.childContext ); } for (var name in childContext) { ("production" !== "development" ? invariant( name in this.constructor.childContextTypes, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', displayName, name ) : invariant(name in this.constructor.childContextTypes)); } return merge(currentContext, childContext); } return currentContext; }, /** * Processes props by setting default values for unspecified props and * asserting that the props are valid. Does not mutate its argument; returns * a new props object with defaults merged in. * * @param {object} newProps * @return {object} * @private */ _processProps: function(newProps) { var props = merge(newProps); var defaultProps = this._defaultProps; for (var propName in defaultProps) { if (typeof props[propName] === 'undefined') { props[propName] = defaultProps[propName]; } } if ("production" !== "development") { var propTypes = this.constructor.propTypes; if (propTypes) { this._checkPropTypes(propTypes, props, ReactPropTypeLocations.prop); } } return props; }, /** * Assert that the props are valid * * @param {object} propTypes Map of prop name to a ReactPropType * @param {object} props * @param {string} location e.g. "prop", "context", "child context" * @private */ _checkPropTypes: function(propTypes, props, location) { var componentName = this.constructor.displayName; for (var propName in propTypes) { if (propTypes.hasOwnProperty(propName)) { propTypes[propName](props, propName, componentName, location); } } }, performUpdateIfNecessary: function() { var compositeLifeCycleState = this._compositeLifeCycleState; // Do not trigger a state transition if we are in the middle of mounting or // receiving props because both of those will already be doing this. if (compositeLifeCycleState === CompositeLifeCycle.MOUNTING || compositeLifeCycleState === CompositeLifeCycle.RECEIVING_PROPS) { return; } ReactComponent.Mixin.performUpdateIfNecessary.call(this); }, /** * If any of `_pendingProps`, `_pendingState`, or `_pendingForceUpdate` is * set, update the component. * * @param {ReactReconcileTransaction} transaction * @internal */ _performUpdateIfNecessary: function(transaction) { if (this._pendingProps == null && this._pendingState == null && this._pendingContext == null && !this._pendingForceUpdate) { return; } var nextFullContext = this._pendingContext || this._currentContext; var nextContext = this._processContext(nextFullContext); this._pendingContext = null; var nextProps = this.props; if (this._pendingProps != null) { nextProps = this._processProps(this._pendingProps); this._pendingProps = null; this._compositeLifeCycleState = CompositeLifeCycle.RECEIVING_PROPS; if (this.componentWillReceiveProps) { this.componentWillReceiveProps(nextProps, nextContext); } } this._compositeLifeCycleState = CompositeLifeCycle.RECEIVING_STATE; // Unlike props, state, and context, we specifically don't want to set // _pendingOwner to null here because it's possible for a component to have // a null owner, so we instead make `this._owner === this._pendingOwner` // mean that there's no owner change pending. var nextOwner = this._pendingOwner; var nextState = this._pendingState || this.state; this._pendingState = null; try { if (this._pendingForceUpdate || !this.shouldComponentUpdate || this.shouldComponentUpdate(nextProps, nextState, nextContext)) { this._pendingForceUpdate = false; // Will set `this.props`, `this.state` and `this.context`. this._performComponentUpdate( nextProps, nextOwner, nextState, nextFullContext, nextContext, transaction ); } else { // If it's determined that a component should not update, we still want // to set props and state. this.props = nextProps; this._owner = nextOwner; this.state = nextState; this._currentContext = nextFullContext; this.context = nextContext; } } finally { this._compositeLifeCycleState = null; } }, /** * Merges new props and state, notifies delegate methods of update and * performs update. * * @param {object} nextProps Next object to set as properties. * @param {?ReactComponent} nextOwner Next component to set as owner * @param {?object} nextState Next object to set as state. * @param {?object} nextFullContext Next object to set as _currentContext. * @param {?object} nextContext Next object to set as context. * @param {ReactReconcileTransaction} transaction * @private */ _performComponentUpdate: function( nextProps, nextOwner, nextState, nextFullContext, nextContext, transaction ) { var prevProps = this.props; var prevOwner = this._owner; var prevState = this.state; var prevContext = this.context; if (this.componentWillUpdate) { this.componentWillUpdate(nextProps, nextState, nextContext); } this.props = nextProps; this._owner = nextOwner; this.state = nextState; this._currentContext = nextFullContext; this.context = nextContext; this.updateComponent( transaction, prevProps, prevOwner, prevState, prevContext ); if (this.componentDidUpdate) { transaction.getReactMountReady().enqueue( this, this.componentDidUpdate.bind(this, prevProps, prevState, prevContext) ); } }, receiveComponent: function(nextComponent, transaction) { if (nextComponent === this._descriptor) { // Since props and context are immutable after the component is // mounted, we can do a cheap identity compare here to determine // if this is a superfluous reconcile. return; } // Update the descriptor that was last used by this component instance this._descriptor = nextComponent; this._pendingContext = nextComponent._currentContext; ReactComponent.Mixin.receiveComponent.call( this, nextComponent, transaction ); }, /** * Updates the component's currently mounted DOM representation. * * By default, this implements React's rendering and reconciliation algorithm. * Sophisticated clients may wish to override this. * * @param {ReactReconcileTransaction} transaction * @param {object} prevProps * @param {?ReactComponent} prevOwner * @param {?object} prevState * @param {?object} prevContext * @internal * @overridable */ updateComponent: ReactPerf.measure( 'ReactCompositeComponent', 'updateComponent', function(transaction, prevProps, prevOwner, prevState, prevContext) { ReactComponent.Mixin.updateComponent.call( this, transaction, prevProps, prevOwner ); var prevComponentInstance = this._renderedComponent; var nextComponent = this._renderValidatedComponent(); if (shouldUpdateReactComponent(prevComponentInstance, nextComponent)) { prevComponentInstance.receiveComponent(nextComponent, transaction); } else { // These two IDs are actually the same! But nothing should rely on that. var thisID = this._rootNodeID; var prevComponentID = prevComponentInstance._rootNodeID; prevComponentInstance.unmountComponent(); this._renderedComponent = instantiateReactComponent(nextComponent); var nextMarkup = this._renderedComponent.mountComponent( thisID, transaction, this._mountDepth + 1 ); ReactComponent.BackendIDOperations.dangerouslyReplaceNodeWithMarkupByID( prevComponentID, nextMarkup ); } } ), /** * Forces an update. This should only be invoked when it is known with * certainty that we are **not** in a DOM transaction. * * You may want to call this when you know that some deeper aspect of the * component's state has changed but `setState` was not called. * * This will not invoke `shouldUpdateComponent`, but it will invoke * `componentWillUpdate` and `componentDidUpdate`. * * @param {?function} callback Called after update is complete. * @final * @protected */ forceUpdate: function(callback) { var compositeLifeCycleState = this._compositeLifeCycleState; ("production" !== "development" ? invariant( this.isMounted() || compositeLifeCycleState === CompositeLifeCycle.MOUNTING, 'forceUpdate(...): Can only force an update on mounted or mounting ' + 'components.' ) : invariant(this.isMounted() || compositeLifeCycleState === CompositeLifeCycle.MOUNTING)); ("production" !== "development" ? invariant( compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE && compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING, 'forceUpdate(...): Cannot force an update while unmounting component ' + 'or during an existing state transition (such as within `render`).' ) : invariant(compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE && compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING)); this._pendingForceUpdate = true; ReactUpdates.enqueueUpdate(this, callback); }, /** * @private */ _renderValidatedComponent: ReactPerf.measure( 'ReactCompositeComponent', '_renderValidatedComponent', function() { var renderedComponent; var previousContext = ReactContext.current; ReactContext.current = this._processChildContext(this._currentContext); ReactCurrentOwner.current = this; try { renderedComponent = this.render(); } finally { ReactContext.current = previousContext; ReactCurrentOwner.current = null; } ("production" !== "development" ? invariant( ReactComponent.isValidComponent(renderedComponent), '%s.render(): A valid ReactComponent must be returned. You may have ' + 'returned null, undefined, an array, or some other invalid object.', this.constructor.displayName || 'ReactCompositeComponent' ) : invariant(ReactComponent.isValidComponent(renderedComponent))); return renderedComponent; } ), /** * @private */ _bindAutoBindMethods: function() { for (var autoBindKey in this.__reactAutoBindMap) { if (!this.__reactAutoBindMap.hasOwnProperty(autoBindKey)) { continue; } var method = this.__reactAutoBindMap[autoBindKey]; this[autoBindKey] = this._bindAutoBindMethod(ReactErrorUtils.guard( method, this.constructor.displayName + '.' + autoBindKey )); } }, /** * Binds a method to the component. * * @param {function} method Method to be bound. * @private */ _bindAutoBindMethod: function(method) { var component = this; var boundMethod = function() { return method.apply(component, arguments); }; if ("production" !== "development") { boundMethod.__reactBoundContext = component; boundMethod.__reactBoundMethod = method; boundMethod.__reactBoundArguments = null; var componentName = component.constructor.displayName; var _bind = boundMethod.bind; boundMethod.bind = function(newThis ) {var args=Array.prototype.slice.call(arguments,1); // User is trying to bind() an autobound method; we effectively will // ignore the value of "this" that the user is trying to use, so // let's warn. if (newThis !== component && newThis !== null) { monitorCodeUse('react_bind_warning', { component: componentName }); console.warn( 'bind(): React component methods may only be bound to the ' + 'component instance. See ' + componentName ); } else if (!args.length) { monitorCodeUse('react_bind_warning', { component: componentName }); console.warn( 'bind(): You are binding a component method to the component. ' + 'React does this for you automatically in a high-performance ' + 'way, so you can safely remove this call. See ' + componentName ); return boundMethod; } var reboundMethod = _bind.apply(boundMethod, arguments); reboundMethod.__reactBoundContext = component; reboundMethod.__reactBoundMethod = method; reboundMethod.__reactBoundArguments = args; return reboundMethod; }; } return boundMethod; }
};
var ReactCompositeComponentBase = function() {}; mixInto(ReactCompositeComponentBase, ReactComponent.Mixin); mixInto(ReactCompositeComponentBase, ReactOwner.Mixin); mixInto(ReactCompositeComponentBase, ReactPropTransferer.Mixin); mixInto(ReactCompositeComponentBase, ReactCompositeComponentMixin);
/**
* Checks if a value is a valid component constructor. * * @param {*} * @return {boolean} * @public */
function isValidClass(componentClass) {
return componentClass instanceof Function && 'componentConstructor' in componentClass && componentClass.componentConstructor instanceof Function;
} /**
* Module for creating composite components. * * @class ReactCompositeComponent * @extends ReactComponent * @extends ReactOwner * @extends ReactPropTransferer */
var ReactCompositeComponent = {
LifeCycle: CompositeLifeCycle, Base: ReactCompositeComponentBase, /** * Creates a composite component class given a class specification. * * @param {object} spec Class specification (which must define `render`). * @return {function} Component constructor function. * @public */ createClass: function(spec) { var Constructor = function() {}; Constructor.prototype = new ReactCompositeComponentBase(); Constructor.prototype.constructor = Constructor; var DescriptorConstructor = Constructor; var ConvenienceConstructor = function(props, children) { var descriptor = new DescriptorConstructor(); descriptor.construct.apply(descriptor, arguments); return descriptor; }; ConvenienceConstructor.componentConstructor = Constructor; Constructor.ConvenienceConstructor = ConvenienceConstructor; ConvenienceConstructor.originalSpec = spec; injectedMixins.forEach( mixSpecIntoComponent.bind(null, ConvenienceConstructor) ); mixSpecIntoComponent(ConvenienceConstructor, spec); ("production" !== "development" ? invariant( Constructor.prototype.render, 'createClass(...): Class specification must implement a `render` method.' ) : invariant(Constructor.prototype.render)); if ("production" !== "development") { if (Constructor.prototype.componentShouldUpdate) { monitorCodeUse( 'react_component_should_update_warning', { component: spec.displayName } ); console.warn( (spec.displayName || 'A component') + ' has a method called ' + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 'The name is phrased as a question because the function is ' + 'expected to return a value.' ); } } // Expose the convience constructor on the prototype so that it can be // easily accessed on descriptors. E.g. <Foo />.type === Foo.type and for // static methods like <Foo />.type.staticMethod(); // This should not be named constructor since this may not be the function // that created the descriptor, and it may not even be a constructor. ConvenienceConstructor.type = Constructor; Constructor.prototype.type = Constructor; // Reduce time spent doing lookups by setting these on the prototype. for (var methodName in ReactCompositeComponentInterface) { if (!Constructor.prototype[methodName]) { Constructor.prototype[methodName] = null; } } if ("production" !== "development") { // In DEV the convenience constructor generates a proxy to another // instance around it to warn about access to properties on the // descriptor. DescriptorConstructor = createDescriptorProxy(Constructor); } return ConvenienceConstructor; }, isValidClass: isValidClass, injection: { injectMixin: function(mixin) { injectedMixins.push(mixin); } }
};
module.exports = ReactCompositeComponent;
},{“./ReactComponent”:31,“./ReactContext”:34,“./ReactCurrentOwner”:35,“./ReactErrorUtils”:51,“./ReactOwner”:64,“./ReactPerf”:65,“./ReactPropTransferer”:66,“./ReactPropTypeLocationNames”:67,“./ReactPropTypeLocations”:68,“./ReactUpdates”:81,“./instantiateReactComponent”:124,“./invariant”:125,“./keyMirror”:131,“./merge”:134,“./mixInto”:137,“./monitorCodeUse”:138,“./objMap”:139,“./shouldUpdateReactComponent”:144,“./warning”:148}],34:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactContext */
“use strict”;
var merge = dereq(“./merge”);
/**
* Keeps track of the current context. * * The context is automatically passed down the component ownership hierarchy * and is accessible via `this.context` on ReactCompositeComponents. */
var ReactContext = {
/** * @internal * @type {object} */ current: {}, /** * Temporarily extends the current context while executing scopedCallback. * * A typical use case might look like * * render: function() { * var children = ReactContext.withContext({foo: 'foo'} () => ( * * )); * return <div>{children}</div>; * } * * @param {object} newContext New context to merge into the existing context * @param {function} scopedCallback Callback to run with the new context * @return {ReactComponent|array<ReactComponent>} */ withContext: function(newContext, scopedCallback) { var result; var previousContext = ReactContext.current; ReactContext.current = merge(previousContext, newContext); try { result = scopedCallback(); } finally { ReactContext.current = previousContext; } return result; }
};
module.exports = ReactContext;
},{“./merge”:134}],35:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactCurrentOwner */
“use strict”;
/**
* Keeps track of the current owner. * * The current owner is the component who should own any components that are * currently being constructed. * * The depth indicate how many composite components are above this render level. */
var ReactCurrentOwner = {
/** * @internal * @type {ReactComponent} */ current: null
};
module.exports = ReactCurrentOwner;
},{}],36:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactDOM * @typechecks static-only */
“use strict”;
var ReactDOMComponent = dereq(“./ReactDOMComponent”);
var mergeInto = dereq(“./mergeInto”); var objMapKeyVal = dereq(“./objMapKeyVal”);
/**
* Creates a new React class that is idempotent and capable of containing other * React components. It accepts event listeners and DOM properties that are * valid according to `DOMProperty`. * * - Event listeners: `onClick`, `onMouseDown`, etc. * - DOM properties: `className`, `name`, `title`, etc. * * The `style` property functions differently from the DOM API. It accepts an * object mapping of style properties to values. * * @param {string} tag Tag name (e.g. `div`). * @param {boolean} omitClose True if the close tag should be omitted. * @private */
function createDOMComponentClass(tag, omitClose) {
var Constructor = function() {}; Constructor.prototype = new ReactDOMComponent(tag, omitClose); Constructor.prototype.constructor = Constructor; Constructor.displayName = tag; var ConvenienceConstructor = function(props, children) { var instance = new Constructor(); instance.construct.apply(instance, arguments); return instance; }; // Expose the constructor on the ConvenienceConstructor and prototype so that // it can be easily easily accessed on descriptors. // E.g. <div />.type === div.type ConvenienceConstructor.type = Constructor; Constructor.prototype.type = Constructor; Constructor.ConvenienceConstructor = ConvenienceConstructor; ConvenienceConstructor.componentConstructor = Constructor; return ConvenienceConstructor;
}
/**
* Creates a mapping from supported HTML tags to `ReactDOMComponent` classes. * This is also accessible via `React.DOM`. * * @public */
var ReactDOM = objMapKeyVal({
a: false, abbr: false, address: false, area: true, article: false, aside: false, audio: false, b: false, base: true, bdi: false, bdo: false, big: false, blockquote: false, body: false, br: true, button: false, canvas: false, caption: false, cite: false, code: false, col: true, colgroup: false, data: false, datalist: false, dd: false, del: false, details: false, dfn: false, div: false, dl: false, dt: false, em: false, embed: true, fieldset: false, figcaption: false, figure: false, footer: false, form: false, // NOTE: Injected, see `ReactDOMForm`. h1: false, h2: false, h3: false, h4: false, h5: false, h6: false, head: false, header: false, hr: true, html: false, i: false, iframe: false, img: true, input: true, ins: false, kbd: false, keygen: true, label: false, legend: false, li: false, link: true, main: false, map: false, mark: false, menu: false, menuitem: false, // NOTE: Close tag should be omitted, but causes problems. meta: true, meter: false, nav: false, noscript: false, object: false, ol: false, optgroup: false, option: false, output: false, p: false, param: true, pre: false, progress: false, q: false, rp: false, rt: false, ruby: false, s: false, samp: false, script: false, section: false, select: false, small: false, source: true, span: false, strong: false, style: false, sub: false, summary: false, sup: false, table: false, tbody: false, td: false, textarea: false, // NOTE: Injected, see `ReactDOMTextarea`. tfoot: false, th: false, thead: false, time: false, title: false, tr: false, track: true, u: false, ul: false, 'var': false, video: false, wbr: true, // SVG circle: false, defs: false, g: false, line: false, linearGradient: false, path: false, polygon: false, polyline: false, radialGradient: false, rect: false, stop: false, svg: false, text: false
}, createDOMComponentClass);
var injection = {
injectComponentClasses: function(componentClasses) { mergeInto(ReactDOM, componentClasses); }
};
ReactDOM.injection = injection;
module.exports = ReactDOM;
},{“./ReactDOMComponent”:38,“./mergeInto”:136,“./objMapKeyVal”:140}],37:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactDOMButton */
“use strict”;
var AutoFocusMixin = dereq(“./AutoFocusMixin”); var ReactBrowserComponentMixin = dereq(“./ReactBrowserComponentMixin”); var ReactCompositeComponent = dereq(“./ReactCompositeComponent”); var ReactDOM = dereq(“./ReactDOM”);
var keyMirror = dereq(“./keyMirror”);
// Store a reference to the <button> `ReactDOMComponent`. var button = ReactDOM.button;
var mouseListenerNames = keyMirror({
onClick: true, onDoubleClick: true, onMouseDown: true, onMouseMove: true, onMouseUp: true, onClickCapture: true, onDoubleClickCapture: true, onMouseDownCapture: true, onMouseMoveCapture: true, onMouseUpCapture: true
});
/**
* Implements a <button> native component that does not receive mouse events * when `disabled` is set. */
var ReactDOMButton = ReactCompositeComponent.createClass({
displayName: 'ReactDOMButton', mixins: [AutoFocusMixin, ReactBrowserComponentMixin], render: function() { var props = {}; // Copy the props; except the mouse listeners if we're disabled for (var key in this.props) { if (this.props.hasOwnProperty(key) && (!this.props.disabled || !mouseListenerNames[key])) { props[key] = this.props[key]; } } return button(props, this.props.children); }
});
module.exports = ReactDOMButton;
},{“./AutoFocusMixin”:1,“./ReactBrowserComponentMixin”:27,“./ReactCompositeComponent”:33,“./ReactDOM”:36,“./keyMirror”:131}],38:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactDOMComponent * @typechecks static-only */
“use strict”;
var CSSPropertyOperations = dereq(“./CSSPropertyOperations”); var DOMProperty = dereq(“./DOMProperty”); var DOMPropertyOperations = dereq(“./DOMPropertyOperations”); var ReactBrowserComponentMixin = dereq(“./ReactBrowserComponentMixin”); var ReactComponent = dereq(“./ReactComponent”); var ReactEventEmitter = dereq(“./ReactEventEmitter”); var ReactMount = dereq(“./ReactMount”); var ReactMultiChild = dereq(“./ReactMultiChild”); var ReactPerf = dereq(“./ReactPerf”);
var escapeTextForBrowser = dereq(“./escapeTextForBrowser”); var invariant = dereq(“./invariant”); var keyOf = dereq(“./keyOf”); var merge = dereq(“./merge”); var mixInto = dereq(“./mixInto”);
var deleteListener = ReactEventEmitter.deleteListener; var listenTo = ReactEventEmitter.listenTo; var registrationNameModules = ReactEventEmitter.registrationNameModules;
// For quickly matching children type, to test if can be treated as content. var CONTENT_TYPES = {'string': true, 'number': true};
var STYLE = keyOf({style: null});
var ELEMENT_NODE_TYPE = 1;
/**
* @param {?object} props */
function assertValidProps(props) {
if (!props) { return; } // Note the use of `==` which checks for null or undefined. ("production" !== "development" ? invariant( props.children == null || props.dangerouslySetInnerHTML == null, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.' ) : invariant(props.children == null || props.dangerouslySetInnerHTML == null)); ("production" !== "development" ? invariant( props.style == null || typeof props.style === 'object', 'The `style` prop expects a mapping from style properties to values, ' + 'not a string.' ) : invariant(props.style == null || typeof props.style === 'object'));
}
function putListener(id, registrationName, listener, transaction) {
var container = ReactMount.findReactContainerForID(id); if (container) { var doc = container.nodeType === ELEMENT_NODE_TYPE ? container.ownerDocument : container; listenTo(registrationName, doc); } transaction.getPutListenerQueue().enqueuePutListener( id, registrationName, listener );
}
/**
* @constructor ReactDOMComponent * @extends ReactComponent * @extends ReactMultiChild */
function ReactDOMComponent(tag, omitClose) {
this._tagOpen = '<' + tag; this._tagClose = omitClose ? '' : '</' + tag + '>'; this.tagName = tag.toUpperCase();
}
ReactDOMComponent.Mixin = {
/** * 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 {number} mountDepth number of components in the owner hierarchy * @return {string} The computed markup. */ mountComponent: ReactPerf.measure( 'ReactDOMComponent', 'mountComponent', function(rootID, transaction, mountDepth) { ReactComponent.Mixin.mountComponent.call( this, rootID, transaction, mountDepth ); assertValidProps(this.props); return ( this._createOpenTagMarkupAndPutListeners(transaction) + this._createContentMarkup(transaction) + this._tagClose ); } ), /** * Creates markup for the open tag and all attributes. * * This method has side effects because events get registered. * * Iterating over object properties is faster than iterating over arrays. * @see http://jsperf.com/obj-vs-arr-iteration * * @private * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction * @return {string} Markup of opening tag. */ _createOpenTagMarkupAndPutListeners: function(transaction) { var props = this.props; var ret = this._tagOpen; for (var propKey in props) { if (!props.hasOwnProperty(propKey)) { continue; } var propValue = props[propKey]; if (propValue == null) { continue; } if (registrationNameModules[propKey]) { putListener(this._rootNodeID, propKey, propValue, transaction); } else { if (propKey === STYLE) { if (propValue) { propValue = props.style = merge(props.style); } propValue = CSSPropertyOperations.createMarkupForStyles(propValue); } var markup = DOMPropertyOperations.createMarkupForProperty(propKey, propValue); if (markup) { ret += ' ' + markup; } } } // For static pages, no need to put React ID and checksum. Saves lots of // bytes. if (transaction.renderToStaticMarkup) { return ret + '>'; } var markupForID = DOMPropertyOperations.createMarkupForID(this._rootNodeID); return ret + ' ' + markupForID + '>'; }, /** * Creates markup for the content between the tags. * * @private * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction * @return {string} Content markup. */ _createContentMarkup: function(transaction) { // Intentional use of != to avoid catching zero/false. var innerHTML = this.props.dangerouslySetInnerHTML; if (innerHTML != null) { if (innerHTML.__html != null) { return innerHTML.__html; } } else { var contentToUse = CONTENT_TYPES[typeof this.props.children] ? this.props.children : null; var childrenToUse = contentToUse != null ? null : this.props.children; if (contentToUse != null) { return escapeTextForBrowser(contentToUse); } else if (childrenToUse != null) { var mountImages = this.mountChildren( childrenToUse, transaction ); return mountImages.join(''); } } return ''; }, receiveComponent: function(nextComponent, transaction) { if (nextComponent === this) { // Since props and context are immutable after the component is // mounted, we can do a cheap identity compare here to determine // if this is a superfluous reconcile. // TODO: compare the descriptor return; } assertValidProps(nextComponent.props); ReactComponent.Mixin.receiveComponent.call( this, nextComponent, transaction ); }, /** * Updates a native DOM component after it has already been allocated and * attached to the DOM. Reconciles the root DOM node, then recurses. * * @param {ReactReconcileTransaction} transaction * @param {object} prevProps * @internal * @overridable */ updateComponent: ReactPerf.measure( 'ReactDOMComponent', 'updateComponent', function(transaction, prevProps, prevOwner) { ReactComponent.Mixin.updateComponent.call( this, transaction, prevProps, prevOwner ); this._updateDOMProperties(prevProps, transaction); this._updateDOMChildren(prevProps, transaction); } ), /** * Reconciles the properties by detecting differences in property values and * updating the DOM as necessary. This function is probably the single most * critical path for performance optimization. * * TODO: Benchmark whether checking for changed values in memory actually * improves performance (especially statically positioned elements). * TODO: Benchmark the effects of putting this at the top since 99% of props * do not change for a given reconciliation. * TODO: Benchmark areas that can be improved with caching. * * @private * @param {object} lastProps * @param {ReactReconcileTransaction} transaction */ _updateDOMProperties: function(lastProps, transaction) { var nextProps = this.props; var propKey; var styleName; var styleUpdates; for (propKey in lastProps) { if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey)) { continue; } if (propKey === STYLE) { var lastStyle = lastProps[propKey]; for (styleName in lastStyle) { if (lastStyle.hasOwnProperty(styleName)) { styleUpdates = styleUpdates || {}; styleUpdates[styleName] = ''; } } } else if (registrationNameModules[propKey]) { deleteListener(this._rootNodeID, propKey); } else if ( DOMProperty.isStandardName[propKey] || DOMProperty.isCustomAttribute(propKey)) { ReactComponent.BackendIDOperations.deletePropertyByID( this._rootNodeID, propKey ); } } for (propKey in nextProps) { var nextProp = nextProps[propKey]; var lastProp = lastProps[propKey]; if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp) { continue; } if (propKey === STYLE) { if (nextProp) { nextProp = nextProps.style = merge(nextProp); } if (lastProp) { // Unset styles on `lastProp` but not on `nextProp`. for (styleName in lastProp) { if (lastProp.hasOwnProperty(styleName) && !nextProp.hasOwnProperty(styleName)) { styleUpdates = styleUpdates || {}; styleUpdates[styleName] = ''; } } // Update styles that changed since `lastProp`. for (styleName in nextProp) { if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) { styleUpdates = styleUpdates || {}; styleUpdates[styleName] = nextProp[styleName]; } } } else { // Relies on `updateStylesByID` not mutating `styleUpdates`. styleUpdates = nextProp; } } else if (registrationNameModules[propKey]) { putListener(this._rootNodeID, propKey, nextProp, transaction); } else if ( DOMProperty.isStandardName[propKey] || DOMProperty.isCustomAttribute(propKey)) { ReactComponent.BackendIDOperations.updatePropertyByID( this._rootNodeID, propKey, nextProp ); } } if (styleUpdates) { ReactComponent.BackendIDOperations.updateStylesByID( this._rootNodeID, styleUpdates ); } }, /** * Reconciles the children with the various properties that affect the * children content. * * @param {object} lastProps * @param {ReactReconcileTransaction} transaction */ _updateDOMChildren: function(lastProps, transaction) { var nextProps = this.props; var lastContent = CONTENT_TYPES[typeof lastProps.children] ? lastProps.children : null; var nextContent = CONTENT_TYPES[typeof nextProps.children] ? nextProps.children : null; var lastHtml = lastProps.dangerouslySetInnerHTML && lastProps.dangerouslySetInnerHTML.__html; var nextHtml = nextProps.dangerouslySetInnerHTML && nextProps.dangerouslySetInnerHTML.__html; // Note the use of `!=` which checks for null or undefined. var lastChildren = lastContent != null ? null : lastProps.children; var nextChildren = nextContent != null ? null : nextProps.children; // If we're switching from children to content/html or vice versa, remove // the old content var lastHasContentOrHtml = lastContent != null || lastHtml != null; var nextHasContentOrHtml = nextContent != null || nextHtml != null; if (lastChildren != null && nextChildren == null) { this.updateChildren(null, transaction); } else if (lastHasContentOrHtml && !nextHasContentOrHtml) { this.updateTextContent(''); } if (nextContent != null) { if (lastContent !== nextContent) { this.updateTextContent('' + nextContent); } } else if (nextHtml != null) { if (lastHtml !== nextHtml) { ReactComponent.BackendIDOperations.updateInnerHTMLByID( this._rootNodeID, nextHtml ); } } else if (nextChildren != null) { this.updateChildren(nextChildren, transaction); } }, /** * Destroys all event registrations for this instance. Does not remove from * the DOM. That must be done by the parent. * * @internal */ unmountComponent: function() { this.unmountChildren(); ReactEventEmitter.deleteAllListeners(this._rootNodeID); ReactComponent.Mixin.unmountComponent.call(this); }
};
mixInto(ReactDOMComponent, ReactComponent.Mixin); mixInto(ReactDOMComponent, ReactDOMComponent.Mixin); mixInto(ReactDOMComponent, ReactMultiChild.Mixin); mixInto(ReactDOMComponent, ReactBrowserComponentMixin);
module.exports = ReactDOMComponent;
},{“./CSSPropertyOperations”:4,“./DOMProperty”:9,“./DOMPropertyOperations”:10,“./ReactBrowserComponentMixin”:27,“./ReactComponent”:31,“./ReactEventEmitter”:52,“./ReactMount”:60,“./ReactMultiChild”:62,“./ReactPerf”:65,“./escapeTextForBrowser”:111,“./invariant”:125,“./keyOf”:132,“./merge”:134,“./mixInto”:137}],39:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactDOMForm */
“use strict”;
var ReactBrowserComponentMixin = dereq(“./ReactBrowserComponentMixin”); var ReactCompositeComponent = dereq(“./ReactCompositeComponent”); var ReactDOM = dereq(“./ReactDOM”); var ReactEventEmitter = dereq(“./ReactEventEmitter”); var EventConstants = dereq(“./EventConstants”);
// Store a reference to the <form> `ReactDOMComponent`. var form = ReactDOM.form;
/**
* Since onSubmit doesn't bubble OR capture on the top level in IE8, we need * to capture it on the <form> element itself. There are lots of hacks we could * do to accomplish this, but the most reliable is to make <form> a * composite component and use `componentDidMount` to attach the event handlers. */
var ReactDOMForm = ReactCompositeComponent.createClass({
displayName: 'ReactDOMForm', mixins: [ReactBrowserComponentMixin], render: function() { // TODO: Instead of using `ReactDOM` directly, we should use JSX. However, // `jshint` fails to parse JSX so in order for linting to work in the open // source repo, we need to just use `ReactDOM.form`. return this.transferPropsTo(form(null, this.props.children)); }, componentDidMount: function() { ReactEventEmitter.trapBubbledEvent( EventConstants.topLevelTypes.topReset, 'reset', this.getDOMNode() ); ReactEventEmitter.trapBubbledEvent( EventConstants.topLevelTypes.topSubmit, 'submit', this.getDOMNode() ); }
});
module.exports = ReactDOMForm;
},{“./EventConstants”:15,“./ReactBrowserComponentMixin”:27,“./ReactCompositeComponent”:33,“./ReactDOM”:36,“./ReactEventEmitter”:52}],40:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactDOMIDOperations * @typechecks static-only */
/*jslint evil: true */
“use strict”;
var CSSPropertyOperations = dereq(“./CSSPropertyOperations”); var DOMChildrenOperations = dereq(“./DOMChildrenOperations”); var DOMPropertyOperations = dereq(“./DOMPropertyOperations”); var ReactMount = dereq(“./ReactMount”); var ReactPerf = dereq(“./ReactPerf”);
var invariant = dereq(“./invariant”);
/**
* Errors for properties that should not be updated with `updatePropertyById()`. * * @type {object} * @private */
var INVALID_PROPERTY_ERRORS = {
dangerouslySetInnerHTML: '`dangerouslySetInnerHTML` must be set using `updateInnerHTMLByID()`.', style: '`style` must be set using `updateStylesByID()`.'
};
var useWhitespaceWorkaround;
/**
* Operations used to process updates to DOM nodes. This is made injectable via * `ReactComponent.BackendIDOperations`. */
var ReactDOMIDOperations = {
/** * Updates a DOM node with new property values. This should only be used to * update DOM properties in `DOMProperty`. * * @param {string} id ID of the node to update. * @param {string} name A valid property name, see `DOMProperty`. * @param {*} value New value of the property. * @internal */ updatePropertyByID: ReactPerf.measure( 'ReactDOMIDOperations', 'updatePropertyByID', function(id, name, value) { var node = ReactMount.getNode(id); ("production" !== "development" ? invariant( !INVALID_PROPERTY_ERRORS.hasOwnProperty(name), 'updatePropertyByID(...): %s', INVALID_PROPERTY_ERRORS[name] ) : invariant(!INVALID_PROPERTY_ERRORS.hasOwnProperty(name))); // If we're updating to null or undefined, we should remove the property // from the DOM node instead of inadvertantly setting to a string. This // brings us in line with the same behavior we have on initial render. if (value != null) { DOMPropertyOperations.setValueForProperty(node, name, value); } else { DOMPropertyOperations.deleteValueForProperty(node, name); } } ), /** * Updates a DOM node to remove a property. This should only be used to remove * DOM properties in `DOMProperty`. * * @param {string} id ID of the node to update. * @param {string} name A property name to remove, see `DOMProperty`. * @internal */ deletePropertyByID: ReactPerf.measure( 'ReactDOMIDOperations', 'deletePropertyByID', function(id, name, value) { var node = ReactMount.getNode(id); ("production" !== "development" ? invariant( !INVALID_PROPERTY_ERRORS.hasOwnProperty(name), 'updatePropertyByID(...): %s', INVALID_PROPERTY_ERRORS[name] ) : invariant(!INVALID_PROPERTY_ERRORS.hasOwnProperty(name))); DOMPropertyOperations.deleteValueForProperty(node, name, value); } ), /** * Updates a DOM node with new style values. If a value is specified as '', * the corresponding style property will be unset. * * @param {string} id ID of the node to update. * @param {object} styles Mapping from styles to values. * @internal */ updateStylesByID: ReactPerf.measure( 'ReactDOMIDOperations', 'updateStylesByID', function(id, styles) { var node = ReactMount.getNode(id); CSSPropertyOperations.setValueForStyles(node, styles); } ), /** * Updates a DOM node's innerHTML. * * @param {string} id ID of the node to update. * @param {string} html An HTML string. * @internal */ updateInnerHTMLByID: ReactPerf.measure( 'ReactDOMIDOperations', 'updateInnerHTMLByID', function(id, html) { var node = ReactMount.getNode(id); // IE8: When updating a just created node with innerHTML only leading // whitespace is removed. When updating an existing node with innerHTML // whitespace in root TextNodes is also collapsed. // @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html if (useWhitespaceWorkaround === undefined) { // Feature detection; only IE8 is known to behave improperly like this. var temp = document.createElement('div'); temp.innerHTML = ' '; useWhitespaceWorkaround = temp.innerHTML === ''; } if (useWhitespaceWorkaround) { // Magic theory: IE8 supposedly differentiates between added and updated // nodes when processing innerHTML, innerHTML on updated nodes suffers // from worse whitespace behavior. Re-adding a node like this triggers // the initial and more favorable whitespace behavior. node.parentNode.replaceChild(node, node); } if (useWhitespaceWorkaround && html.match(/^[ \r\n\t\f]/)) { // Recover leading whitespace by temporarily prepending any character. // \uFEFF has the potential advantage of being zero-width/invisible. node.innerHTML = '\uFEFF' + html; node.firstChild.deleteData(0, 1); } else { node.innerHTML = html; } } ), /** * Updates a DOM node's text content set by `props.content`. * * @param {string} id ID of the node to update. * @param {string} content Text content. * @internal */ updateTextContentByID: ReactPerf.measure( 'ReactDOMIDOperations', 'updateTextContentByID', function(id, content) { var node = ReactMount.getNode(id); DOMChildrenOperations.updateTextContent(node, content); } ), /** * Replaces a DOM node that exists in the document with markup. * * @param {string} id ID of child to be replaced. * @param {string} markup Dangerous markup to inject in place of child. * @internal * @see {Danger.dangerouslyReplaceNodeWithMarkup} */ dangerouslyReplaceNodeWithMarkupByID: ReactPerf.measure( 'ReactDOMIDOperations', 'dangerouslyReplaceNodeWithMarkupByID', function(id, markup) { var node = ReactMount.getNode(id); DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup(node, markup); } ), /** * Updates a component's children by processing a series of updates. * * @param {array<object>} updates List of update configurations. * @param {array<string>} markup List of markup strings. * @internal */ dangerouslyProcessChildrenUpdates: ReactPerf.measure( 'ReactDOMIDOperations', 'dangerouslyProcessChildrenUpdates', function(updates, markup) { for (var i = 0; i < updates.length; i++) { updates[i].parentNode = ReactMount.getNode(updates[i].parentID); } DOMChildrenOperations.processUpdates(updates, markup); } )
};
module.exports = ReactDOMIDOperations;
},{“./CSSPropertyOperations”:4,“./DOMChildrenOperations”:8,“./DOMPropertyOperations”:10,“./ReactMount”:60,“./ReactPerf”:65,“./invariant”:125}],41:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactDOMImg */
“use strict”;
var ReactBrowserComponentMixin = dereq(“./ReactBrowserComponentMixin”); var ReactCompositeComponent = dereq(“./ReactCompositeComponent”); var ReactDOM = dereq(“./ReactDOM”); var ReactEventEmitter = dereq(“./ReactEventEmitter”); var EventConstants = dereq(“./EventConstants”);
// Store a reference to the <img> `ReactDOMComponent`. var img = ReactDOM.img;
/**
* Since onLoad doesn't bubble OR capture on the top level in IE8, we need to * capture it on the <img> element itself. There are lots of hacks we could do * to accomplish this, but the most reliable is to make <img> a composite * component and use `componentDidMount` to attach the event handlers. */
var ReactDOMImg = ReactCompositeComponent.createClass({
displayName: 'ReactDOMImg', tagName: 'IMG', mixins: [ReactBrowserComponentMixin], render: function() { return img(this.props); }, componentDidMount: function() { var node = this.getDOMNode(); ReactEventEmitter.trapBubbledEvent( EventConstants.topLevelTypes.topLoad, 'load', node ); ReactEventEmitter.trapBubbledEvent( EventConstants.topLevelTypes.topError, 'error', node ); }
});
module.exports = ReactDOMImg;
},{“./EventConstants”:15,“./ReactBrowserComponentMixin”:27,“./ReactCompositeComponent”:33,“./ReactDOM”:36,“./ReactEventEmitter”:52}],42:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactDOMInput */
“use strict”;
var AutoFocusMixin = dereq(“./AutoFocusMixin”); var DOMPropertyOperations = dereq(“./DOMPropertyOperations”); var LinkedValueUtils = dereq(“./LinkedValueUtils”); var ReactBrowserComponentMixin = dereq(“./ReactBrowserComponentMixin”); var ReactCompositeComponent = dereq(“./ReactCompositeComponent”); var ReactDOM = dereq(“./ReactDOM”); var ReactMount = dereq(“./ReactMount”);
var invariant = dereq(“./invariant”); var merge = dereq(“./merge”);
// Store a reference to the <input> `ReactDOMComponent`. var input = ReactDOM.input;
var instancesByReactID = {};
/**
* Implements an <input> native component that allows setting these optional * props: `checked`, `value`, `defaultChecked`, and `defaultValue`. * * If `checked` or `value` are not supplied (or null/undefined), user actions * that affect the checked state or value will trigger updates to the element. * * If they are supplied (and not null/undefined), the rendered element will not * trigger updates to the element. Instead, the props must change in order for * the rendered element to be updated. * * The rendered element will be initialized as unchecked (or `defaultChecked`) * with an empty value (or `defaultValue`). * * @see http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html */
var ReactDOMInput = ReactCompositeComponent.createClass({
displayName: 'ReactDOMInput', mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin], getInitialState: function() { var defaultValue = this.props.defaultValue; return { checked: this.props.defaultChecked || false, value: defaultValue != null ? defaultValue : null }; }, shouldComponentUpdate: function() { // Defer any updates to this component during the `onChange` handler. return !this._isChanging; }, render: function() { // Clone `this.props` so we don't mutate the input. var props = merge(this.props); props.defaultChecked = null; props.defaultValue = null; var value = LinkedValueUtils.getValue(this); props.value = value != null ? value : this.state.value; var checked = LinkedValueUtils.getChecked(this); props.checked = checked != null ? checked : this.state.checked; props.onChange = this._handleChange; return input(props, this.props.children); }, componentDidMount: function() { var id = ReactMount.getID(this.getDOMNode()); instancesByReactID[id] = this; }, componentWillUnmount: function() { var rootNode = this.getDOMNode(); var id = ReactMount.getID(rootNode); delete instancesByReactID[id]; }, componentDidUpdate: function(prevProps, prevState, prevContext) { var rootNode = this.getDOMNode(); if (this.props.checked != null) { DOMPropertyOperations.setValueForProperty( rootNode, 'checked', this.props.checked || false ); } var value = LinkedValueUtils.getValue(this); 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. DOMPropertyOperations.setValueForProperty(rootNode, 'value', '' + value); } }, _handleChange: function(event) { var returnValue; var onChange = LinkedValueUtils.getOnChange(this); if (onChange) { this._isChanging = true; returnValue = onChange.call(this, event); this._isChanging = false; } this.setState({ checked: event.target.checked, value: event.target.value }); var name = this.props.name; if (this.props.type === 'radio' && name != null) { var rootNode = this.getDOMNode(); var queryRoot = rootNode; while (queryRoot.parentNode) { queryRoot = queryRoot.parentNode; } // If `rootNode.form` was non-null, then we could try `form.elements`, // but that sometimes behaves strangely in IE8. We could also try using // `form.getElementsByName`, but that will only return direct children // and won't include inputs that use the HTML5 `form=` attribute. Since // the input might not even be in a form, let's just use the global // `querySelectorAll` to ensure we don't miss anything. var group = queryRoot.querySelectorAll( 'input[name=' + JSON.stringify('' + name) + '][type="radio"]'); for (var i = 0, groupLen = group.length; i < groupLen; i++) { var otherNode = group[i]; if (otherNode === rootNode || otherNode.form !== rootNode.form) { continue; } var otherID = ReactMount.getID(otherNode); ("production" !== "development" ? invariant( otherID, 'ReactDOMInput: Mixing React and non-React radio inputs with the ' + 'same `name` is not supported.' ) : invariant(otherID)); var otherInstance = instancesByReactID[otherID]; ("production" !== "development" ? invariant( otherInstance, 'ReactDOMInput: Unknown radio button ID %s.', otherID ) : invariant(otherInstance)); // In some cases, this will actually change the `checked` state value. // In other cases, there's no change but this forces a reconcile upon // which componentDidUpdate will reset the DOM property to whatever it // should be. otherInstance.setState({ checked: false }); } } return returnValue; }
});
module.exports = ReactDOMInput;
},{“./AutoFocusMixin”:1,“./DOMPropertyOperations”:10,“./LinkedValueUtils”:23,“./ReactBrowserComponentMixin”:27,“./ReactCompositeComponent”:33,“./ReactDOM”:36,“./ReactMount”:60,“./invariant”:125,“./merge”:134}],43:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactDOMOption */
“use strict”;
var ReactBrowserComponentMixin = dereq(“./ReactBrowserComponentMixin”); var ReactCompositeComponent = dereq(“./ReactCompositeComponent”); var ReactDOM = dereq(“./ReactDOM”);
var warning = dereq(“./warning”);
// Store a reference to the <option> `ReactDOMComponent`. var option = ReactDOM.option;
/**
* Implements an <option> native component that warns when `selected` is set. */
var ReactDOMOption = ReactCompositeComponent.createClass({
displayName: 'ReactDOMOption', mixins: [ReactBrowserComponentMixin], componentWillMount: function() { // TODO (yungsters): Remove support for `selected` in <option>. if ("production" !== "development") { ("production" !== "development" ? warning( this.props.selected == null, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.' ) : null); } }, render: function() { return option(this.props, this.props.children); }
});
module.exports = ReactDOMOption;
},{“./ReactBrowserComponentMixin”:27,“./ReactCompositeComponent”:33,“./ReactDOM”:36,“./warning”:148}],44:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactDOMSelect */
“use strict”;
var AutoFocusMixin = dereq(“./AutoFocusMixin”); var LinkedValueUtils = dereq(“./LinkedValueUtils”); var ReactBrowserComponentMixin = dereq(“./ReactBrowserComponentMixin”); var ReactCompositeComponent = dereq(“./ReactCompositeComponent”); var ReactDOM = dereq(“./ReactDOM”);
var invariant = dereq(“./invariant”); var merge = dereq(“./merge”);
// Store a reference to the <select> `ReactDOMComponent`. var select = ReactDOM.select;
/**
* Validation function for `value` and `defaultValue`. * @private */
function selectValueType(props, propName, componentName) {
if (props[propName] == null) { return; } if (props.multiple) { ("production" !== "development" ? invariant( Array.isArray(props[propName]), 'The `%s` prop supplied to <select> must be an array if `multiple` is ' + 'true.', propName ) : invariant(Array.isArray(props[propName]))); } else { ("production" !== "development" ? invariant( !Array.isArray(props[propName]), 'The `%s` prop supplied to <select> must be a scalar value if ' + '`multiple` is false.', propName ) : invariant(!Array.isArray(props[propName]))); }
}
/**
* If `value` is supplied, updates <option> elements on mount and update. * @param {ReactComponent} component Instance of ReactDOMSelect * @param {?*} propValue For uncontrolled components, null/undefined. For * controlled components, a string (or with `multiple`, a list of strings). * @private */
function updateOptions(component, propValue) {
var multiple = component.props.multiple; var value = propValue != null ? propValue : component.state.value; var options = component.getDOMNode().options; var selectedValue, i, l; if (multiple) { selectedValue = {}; for (i = 0, l = value.length; i < l; ++i) { selectedValue['' + value[i]] = true; } } else { selectedValue = '' + value; } for (i = 0, l = options.length; i < l; i++) { var selected = multiple ? selectedValue.hasOwnProperty(options[i].value) : options[i].value === selectedValue; if (selected !== options[i].selected) { options[i].selected = selected; } }
}
/**
* Implements a <select> native component that allows optionally setting the * props `value` and `defaultValue`. If `multiple` is false, the prop must be a * string. If `multiple` is true, the prop must be an array of strings. * * If `value` is not supplied (or null/undefined), user actions that change the * selected option will trigger updates to the rendered options. * * If it is supplied (and not null/undefined), the rendered options will not * update in response to user actions. Instead, the `value` prop must change in * order for the rendered options to update. * * If `defaultValue` is provided, any options with the supplied values will be * selected. */
var ReactDOMSelect = ReactCompositeComponent.createClass({
displayName: 'ReactDOMSelect', mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin], propTypes: { defaultValue: selectValueType, value: selectValueType }, getInitialState: function() { return {value: this.props.defaultValue || (this.props.multiple ? [] : '')}; }, componentWillReceiveProps: function(nextProps) { if (!this.props.multiple && nextProps.multiple) { this.setState({value: [this.state.value]}); } else if (this.props.multiple && !nextProps.multiple) { this.setState({value: this.state.value[0]}); } }, shouldComponentUpdate: function() { // Defer any updates to this component during the `onChange` handler. return !this._isChanging; }, render: function() { // Clone `this.props` so we don't mutate the input. var props = merge(this.props); props.onChange = this._handleChange; props.value = null; return select(props, this.props.children); }, componentDidMount: function() { updateOptions(this, LinkedValueUtils.getValue(this)); }, componentDidUpdate: function() { var value = LinkedValueUtils.getValue(this); if (value != null) { updateOptions(this, value); } }, _handleChange: function(event) { var returnValue; var onChange = LinkedValueUtils.getOnChange(this); if (onChange) { this._isChanging = true; returnValue = onChange.call(this, event); this._isChanging = false; } var selectedValue; if (this.props.multiple) { selectedValue = []; var options = event.target.options; for (var i = 0, l = options.length; i < l; i++) { if (options[i].selected) { selectedValue.push(options[i].value); } } } else { selectedValue = event.target.value; } this.setState({value: selectedValue}); return returnValue; }
});
module.exports = ReactDOMSelect;
},{“./AutoFocusMixin”:1,“./LinkedValueUtils”:23,“./ReactBrowserComponentMixin”:27,“./ReactCompositeComponent”:33,“./ReactDOM”:36,“./invariant”:125,“./merge”:134}],45:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactDOMSelection */
“use strict”;
var getNodeForCharacterOffset = dereq(“./getNodeForCharacterOffset”); var getTextContentAccessor = dereq(“./getTextContentAccessor”);
/**
* Get the appropriate anchor and focus node/offset pairs for IE. * * The catch here is that IE's selection API doesn't provide information * about whether the selection is forward or backward, so we have to * behave as though it's always forward. * * IE text differs from modern selection in that it behaves as though * block elements end with a new line. This means character offsets will * differ between the two APIs. * * @param {DOMElement} node * @return {object} */
function getIEOffsets(node) {
var selection = document.selection; var selectedRange = selection.createRange(); var selectedLength = selectedRange.text.length; // Duplicate selection so we can move range without breaking user selection. var fromStart = selectedRange.duplicate(); fromStart.moveToElementText(node); fromStart.setEndPoint('EndToStart', selectedRange); var startOffset = fromStart.text.length; var endOffset = startOffset + selectedLength; return { start: startOffset, end: endOffset };
}
/**
* @param {DOMElement} node * @return {?object} */
function getModernOffsets(node) {
var selection = window.getSelection(); if (selection.rangeCount === 0) { return null; } var anchorNode = selection.anchorNode; var anchorOffset = selection.anchorOffset; var focusNode = selection.focusNode; var focusOffset = selection.focusOffset; var currentRange = selection.getRangeAt(0); var rangeLength = currentRange.toString().length; var tempRange = currentRange.cloneRange(); tempRange.selectNodeContents(node); tempRange.setEnd(currentRange.startContainer, currentRange.startOffset); var start = tempRange.toString().length; var end = start + rangeLength; // Detect whether the selection is backward. var detectionRange = document.createRange(); detectionRange.setStart(anchorNode, anchorOffset); detectionRange.setEnd(focusNode, focusOffset); var isBackward = detectionRange.collapsed; detectionRange.detach(); return { start: isBackward ? end : start, end: isBackward ? start : end };
}
/**
* @param {DOMElement|DOMTextNode} node * @param {object} offsets */
function setIEOffsets(node, offsets) {
var range = document.selection.createRange().duplicate(); var start, end; if (typeof offsets.end === 'undefined') { start = offsets.start; end = start; } else if (offsets.start > offsets.end) { start = offsets.end; end = offsets.start; } else { start = offsets.start; end = offsets.end; } range.moveToElementText(node); range.moveStart('character', start); range.setEndPoint('EndToStart', range); range.moveEnd('character', end - start); range.select();
}
/**
* In modern non-IE browsers, we can support both forward and backward * selections. * * Note: IE10+ supports the Selection object, but it does not support * the `extend` method, which means that even in modern IE, it's not possible * to programatically create a backward selection. Thus, for all IE * versions, we use the old IE API to create our selections. * * @param {DOMElement|DOMTextNode} node * @param {object} offsets */
function setModernOffsets(node, offsets) {
var selection = window.getSelection(); var length = node[getTextContentAccessor()].length; var start = Math.min(offsets.start, length); var end = typeof offsets.end === 'undefined' ? start : Math.min(offsets.end, length); // IE 11 uses modern selection, but doesn't support the extend method. // Flip backward selections, so we can set with a single range. if (!selection.extend && start > end) { var temp = end; end = start; start = temp; } var startMarker = getNodeForCharacterOffset(node, start); var endMarker = getNodeForCharacterOffset(node, end); if (startMarker && endMarker) { var range = document.createRange(); range.setStart(startMarker.node, startMarker.offset); selection.removeAllRanges(); if (start > end) { selection.addRange(range); selection.extend(endMarker.node, endMarker.offset); } else { range.setEnd(endMarker.node, endMarker.offset); selection.addRange(range); } range.detach(); }
}
var ReactDOMSelection = {
/** * @param {DOMElement} node */ getOffsets: function(node) { var getOffsets = document.selection ? getIEOffsets : getModernOffsets; return getOffsets(node); }, /** * @param {DOMElement|DOMTextNode} node * @param {object} offsets */ setOffsets: function(node, offsets) { var setOffsets = document.selection ? setIEOffsets : setModernOffsets; setOffsets(node, offsets); }
};
module.exports = ReactDOMSelection;
},{“./getNodeForCharacterOffset”:119,“./getTextContentAccessor”:121}],46:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactDOMTextarea */
“use strict”;
var AutoFocusMixin = dereq(“./AutoFocusMixin”); var DOMPropertyOperations = dereq(“./DOMPropertyOperations”); var LinkedValueUtils = dereq(“./LinkedValueUtils”); var ReactBrowserComponentMixin = dereq(“./ReactBrowserComponentMixin”); var ReactCompositeComponent = dereq(“./ReactCompositeComponent”); var ReactDOM = dereq(“./ReactDOM”);
var invariant = dereq(“./invariant”); var merge = dereq(“./merge”);
var warning = dereq(“./warning”);
// Store a reference to the <textarea> `ReactDOMComponent`. var textarea = ReactDOM.textarea;
/**
* Implements a <textarea> native component that allows setting `value`, and * `defaultValue`. This differs from the traditional DOM API because value is * usually set as PCDATA children. * * If `value` is not supplied (or null/undefined), user actions that affect the * value will trigger updates to the element. * * If `value` is supplied (and not null/undefined), the rendered element will * not trigger updates to the element. Instead, the `value` prop must change in * order for the rendered element to be updated. * * The rendered element will be initialized with an empty value, the prop * `defaultValue` if specified, or the children content (deprecated). */
var ReactDOMTextarea = ReactCompositeComponent.createClass({
displayName: 'ReactDOMTextarea', mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin], getInitialState: function() { var defaultValue = this.props.defaultValue; // TODO (yungsters): Remove support for children content in <textarea>. var children = this.props.children; if (children != null) { if ("production" !== "development") { ("production" !== "development" ? warning( false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.' ) : null); } ("production" !== "development" ? invariant( defaultValue == null, 'If you supply `defaultValue` on a <textarea>, do not pass children.' ) : invariant(defaultValue == null)); if (Array.isArray(children)) { ("production" !== "development" ? invariant( children.length <= 1, '<textarea> can only have at most one child.' ) : invariant(children.length <= 1)); children = children[0]; } defaultValue = '' + children; } if (defaultValue == null) { defaultValue = ''; } var value = LinkedValueUtils.getValue(this); return { // We save the initial value so that `ReactDOMComponent` doesn't update // `textContent` (unnecessary since we update value). // The initial value can be a boolean or object so that's why it's // forced to be a string. initialValue: '' + (value != null ? value : defaultValue), value: defaultValue }; }, shouldComponentUpdate: function() { // Defer any updates to this component during the `onChange` handler. return !this._isChanging; }, render: function() { // Clone `this.props` so we don't mutate the input. var props = merge(this.props); var value = LinkedValueUtils.getValue(this); ("production" !== "development" ? invariant( props.dangerouslySetInnerHTML == null, '`dangerouslySetInnerHTML` does not make sense on <textarea>.' ) : invariant(props.dangerouslySetInnerHTML == null)); props.defaultValue = null; props.value = value != null ? value : this.state.value; props.onChange = this._handleChange; // Always set children to the same thing. In IE9, the selection range will // get reset if `textContent` is mutated. return textarea(props, this.state.initialValue); }, componentDidUpdate: function(prevProps, prevState, prevContext) { var value = LinkedValueUtils.getValue(this); if (value != null) { var rootNode = this.getDOMNode(); // Cast `value` to a string to ensure the value is set correctly. While // browsers typically do this as necessary, jsdom doesn't. DOMPropertyOperations.setValueForProperty(rootNode, 'value', '' + value); } }, _handleChange: function(event) { var returnValue; var onChange = LinkedValueUtils.getOnChange(this); if (onChange) { this._isChanging = true; returnValue = onChange.call(this, event); this._isChanging = false; } this.setState({value: event.target.value}); return returnValue; }
});
module.exports = ReactDOMTextarea;
},{“./AutoFocusMixin”:1,“./DOMPropertyOperations”:10,“./LinkedValueUtils”:23,“./ReactBrowserComponentMixin”:27,“./ReactCompositeComponent”:33,“./ReactDOM”:36,“./invariant”:125,“./merge”:134,“./warning”:148}],47:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactDefaultBatchingStrategy */
“use strict”;
var ReactUpdates = dereq(“./ReactUpdates”); var Transaction = dereq(“./Transaction”);
var emptyFunction = dereq(“./emptyFunction”); var mixInto = dereq(“./mixInto”);
var RESET_BATCHED_UPDATES = {
initialize: emptyFunction, close: function() { ReactDefaultBatchingStrategy.isBatchingUpdates = false; }
};
var FLUSH_BATCHED_UPDATES = {
initialize: emptyFunction, close: ReactUpdates.flushBatchedUpdates.bind(ReactUpdates)
};
var TRANSACTION_WRAPPERS = [FLUSH_BATCHED_UPDATES, RESET_BATCHED_UPDATES];
function ReactDefaultBatchingStrategyTransaction() {
this.reinitializeTransaction();
}
mixInto(ReactDefaultBatchingStrategyTransaction, Transaction.Mixin); mixInto(ReactDefaultBatchingStrategyTransaction, {
getTransactionWrappers: function() { return TRANSACTION_WRAPPERS; }
});
var transaction = new ReactDefaultBatchingStrategyTransaction();
var ReactDefaultBatchingStrategy = {
isBatchingUpdates: false, /** * Call the provided function in a context within which calls to `setState` * and friends are batched such that components aren't updated unnecessarily. */ batchedUpdates: function(callback, param) { var alreadyBatchingUpdates = ReactDefaultBatchingStrategy.isBatchingUpdates; ReactDefaultBatchingStrategy.isBatchingUpdates = true; // The code is written this way to avoid extra allocations if (alreadyBatchingUpdates) { callback(param); } else { transaction.perform(callback, null, param); } }
};
module.exports = ReactDefaultBatchingStrategy;
},{“./ReactUpdates”:81,“./Transaction”:96,“./emptyFunction”:109,“./mixInto”:137}],48:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactDefaultInjection */
“use strict”;
var ReactInjection = dereq(“./ReactInjection”);
var ExecutionEnvironment = dereq(“./ExecutionEnvironment”);
var DefaultDOMPropertyConfig = dereq(“./DefaultDOMPropertyConfig”);
var ChangeEventPlugin = dereq(“./ChangeEventPlugin”); var ClientReactRootIndex = dereq(“./ClientReactRootIndex”); var CompositionEventPlugin = dereq(“./CompositionEventPlugin”); var DefaultEventPluginOrder = dereq(“./DefaultEventPluginOrder”); var EnterLeaveEventPlugin = dereq(“./EnterLeaveEventPlugin”); var MobileSafariClickEventPlugin = dereq(“./MobileSafariClickEventPlugin”); var ReactBrowserComponentMixin = dereq(“./ReactBrowserComponentMixin”); var ReactComponentBrowserEnvironment =
_dereq_("./ReactComponentBrowserEnvironment");
var ReactEventTopLevelCallback = dereq(“./ReactEventTopLevelCallback”); var ReactDOM = dereq(“./ReactDOM”); var ReactDOMButton = dereq(“./ReactDOMButton”); var ReactDOMForm = dereq(“./ReactDOMForm”); var ReactDOMImg = dereq(“./ReactDOMImg”); var ReactDOMInput = dereq(“./ReactDOMInput”); var ReactDOMOption = dereq(“./ReactDOMOption”); var ReactDOMSelect = dereq(“./ReactDOMSelect”); var ReactDOMTextarea = dereq(“./ReactDOMTextarea”); var ReactInstanceHandles = dereq(“./ReactInstanceHandles”); var ReactMount = dereq(“./ReactMount”); var SelectEventPlugin = dereq(“./SelectEventPlugin”); var ServerReactRootIndex = dereq(“./ServerReactRootIndex”); var SimpleEventPlugin = dereq(“./SimpleEventPlugin”);
var ReactDefaultBatchingStrategy = dereq(“./ReactDefaultBatchingStrategy”);
var createFullPageComponent = dereq(“./createFullPageComponent”);
function inject() {
ReactInjection.EventEmitter.injectTopLevelCallbackCreator( ReactEventTopLevelCallback ); /** * Inject modules for resolving DOM hierarchy and plugin ordering. */ ReactInjection.EventPluginHub.injectEventPluginOrder(DefaultEventPluginOrder); ReactInjection.EventPluginHub.injectInstanceHandle(ReactInstanceHandles); ReactInjection.EventPluginHub.injectMount(ReactMount); /** * Some important event plugins included by default (without having to require * them). */ ReactInjection.EventPluginHub.injectEventPluginsByName({ SimpleEventPlugin: SimpleEventPlugin, EnterLeaveEventPlugin: EnterLeaveEventPlugin, ChangeEventPlugin: ChangeEventPlugin, CompositionEventPlugin: CompositionEventPlugin, MobileSafariClickEventPlugin: MobileSafariClickEventPlugin, SelectEventPlugin: SelectEventPlugin }); ReactInjection.DOM.injectComponentClasses({ button: ReactDOMButton, form: ReactDOMForm, img: ReactDOMImg, input: ReactDOMInput, option: ReactDOMOption, select: ReactDOMSelect, textarea: ReactDOMTextarea, html: createFullPageComponent(ReactDOM.html), head: createFullPageComponent(ReactDOM.head), title: createFullPageComponent(ReactDOM.title), body: createFullPageComponent(ReactDOM.body) }); // This needs to happen after createFullPageComponent() otherwise the mixin // gets double injected. ReactInjection.CompositeComponent.injectMixin(ReactBrowserComponentMixin); ReactInjection.DOMProperty.injectDOMPropertyConfig(DefaultDOMPropertyConfig); ReactInjection.Updates.injectBatchingStrategy( ReactDefaultBatchingStrategy ); ReactInjection.RootIndex.injectCreateReactRootIndex( ExecutionEnvironment.canUseDOM ? ClientReactRootIndex.createReactRootIndex : ServerReactRootIndex.createReactRootIndex ); ReactInjection.Component.injectEnvironment(ReactComponentBrowserEnvironment); if ("production" !== "development") { var url = (ExecutionEnvironment.canUseDOM && window.location.href) || ''; if ((/[?&]react_perf\b/).test(url)) { var ReactDefaultPerf = _dereq_("./ReactDefaultPerf"); ReactDefaultPerf.start(); } }
}
module.exports = {
inject: inject
};
},{“./ChangeEventPlugin”:5,“./ClientReactRootIndex”:6,“./CompositionEventPlugin”:7,“./DefaultDOMPropertyConfig”:12,“./DefaultEventPluginOrder”:13,“./EnterLeaveEventPlugin”:14,“./ExecutionEnvironment”:21,“./MobileSafariClickEventPlugin”:24,“./ReactBrowserComponentMixin”:27,“./ReactComponentBrowserEnvironment”:32,“./ReactDOM”:36,“./ReactDOMButton”:37,“./ReactDOMForm”:39,“./ReactDOMImg”:41,“./ReactDOMInput”:42,“./ReactDOMOption”:43,“./ReactDOMSelect”:44,“./ReactDOMTextarea”:46,“./ReactDefaultBatchingStrategy”:47,“./ReactDefaultPerf”:49,“./ReactEventTopLevelCallback”:54,“./ReactInjection”:55,“./ReactInstanceHandles”:57,“./ReactMount”:60,“./SelectEventPlugin”:83,“./ServerReactRootIndex”:84,“./SimpleEventPlugin”:85,“./createFullPageComponent”:104}],49:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactDefaultPerf * @typechecks static-only */
“use strict”;
var DOMProperty = dereq(“./DOMProperty”); var ReactDefaultPerfAnalysis = dereq(“./ReactDefaultPerfAnalysis”); var ReactMount = dereq(“./ReactMount”); var ReactPerf = dereq(“./ReactPerf”);
var performanceNow = dereq(“./performanceNow”);
function roundFloat(val) {
return Math.floor(val * 100) / 100;
}
var ReactDefaultPerf = {
_allMeasurements: [], // last item in the list is the current one _injected: false, start: function() { if (!ReactDefaultPerf._injected) { ReactPerf.injection.injectMeasure(ReactDefaultPerf.measure); } ReactDefaultPerf._allMeasurements.length = 0; ReactPerf.enableMeasure = true; }, stop: function() { ReactPerf.enableMeasure = false; }, getLastMeasurements: function() { return ReactDefaultPerf._allMeasurements; }, printExclusive: function(measurements) { measurements = measurements || ReactDefaultPerf._allMeasurements; var summary = ReactDefaultPerfAnalysis.getExclusiveSummary(measurements); console.table(summary.map(function(item) { return { 'Component class name': item.componentName, 'Total inclusive time (ms)': roundFloat(item.inclusive), 'Total exclusive time (ms)': roundFloat(item.exclusive), 'Exclusive time per instance (ms)': roundFloat(item.exclusive / item.count), 'Instances': item.count }; })); console.log( 'Total time:', ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms' ); }, printInclusive: function(measurements) { measurements = measurements || ReactDefaultPerf._allMeasurements; var summary = ReactDefaultPerfAnalysis.getInclusiveSummary(measurements); console.table(summary.map(function(item) { return { 'Owner > component': item.componentName, 'Inclusive time (ms)': roundFloat(item.time), 'Instances': item.count }; })); console.log( 'Total time:', ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms' ); }, printWasted: function(measurements) { measurements = measurements || ReactDefaultPerf._allMeasurements; var summary = ReactDefaultPerfAnalysis.getInclusiveSummary( measurements, true ); console.table(summary.map(function(item) { return { 'Owner > component': item.componentName, 'Wasted time (ms)': item.time, 'Instances': item.count }; })); console.log( 'Total time:', ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms' ); }, printDOM: function(measurements) { measurements = measurements || ReactDefaultPerf._allMeasurements; var summary = ReactDefaultPerfAnalysis.getDOMSummary(measurements); console.table(summary.map(function(item) { var result = {}; result[DOMProperty.ID_ATTRIBUTE_NAME] = item.id; result['type'] = item.type; result['args'] = JSON.stringify(item.args); return result; })); console.log( 'Total time:', ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms' ); }, _recordWrite: function(id, fnName, totalTime, args) { // TODO: totalTime isn't that useful since it doesn't count paints/reflows var writes = ReactDefaultPerf ._allMeasurements[ReactDefaultPerf._allMeasurements.length - 1] .writes; writes[id] = writes[id] || []; writes[id].push({ type: fnName, time: totalTime, args: args }); }, measure: function(moduleName, fnName, func) { return function() {var args=Array.prototype.slice.call(arguments,0); var totalTime; var rv; var start; if (fnName === '_renderNewRootComponent' || fnName === 'flushBatchedUpdates') { // A "measurement" is a set of metrics recorded for each flush. We want // to group the metrics for a given flush together so we can look at the // components that rendered and the DOM operations that actually // happened to determine the amount of "wasted work" performed. ReactDefaultPerf._allMeasurements.push({ exclusive: {}, inclusive: {}, counts: {}, writes: {}, displayNames: {}, totalTime: 0 }); start = performanceNow(); rv = func.apply(this, args); ReactDefaultPerf._allMeasurements[ ReactDefaultPerf._allMeasurements.length - 1 ].totalTime = performanceNow() - start; return rv; } else if (moduleName === 'ReactDOMIDOperations' || moduleName === 'ReactComponentBrowserEnvironment') { start = performanceNow(); rv = func.apply(this, args); totalTime = performanceNow() - start; if (fnName === 'mountImageIntoNode') { var mountID = ReactMount.getID(args[1]); ReactDefaultPerf._recordWrite(mountID, fnName, totalTime, args[0]); } else if (fnName === 'dangerouslyProcessChildrenUpdates') { // special format args[0].forEach(function(update) { var writeArgs = {}; if (update.fromIndex !== null) { writeArgs.fromIndex = update.fromIndex; } if (update.toIndex !== null) { writeArgs.toIndex = update.toIndex; } if (update.textContent !== null) { writeArgs.textContent = update.textContent; } if (update.markupIndex !== null) { writeArgs.markup = args[1][update.markupIndex]; } ReactDefaultPerf._recordWrite( update.parentID, update.type, totalTime, writeArgs ); }); } else { // basic format ReactDefaultPerf._recordWrite( args[0], fnName, totalTime, Array.prototype.slice.call(args, 1) ); } return rv; } else if (moduleName === 'ReactCompositeComponent' && ( fnName === 'mountComponent' || fnName === 'updateComponent' || // TODO: receiveComponent()? fnName === '_renderValidatedComponent')) { var rootNodeID = fnName === 'mountComponent' ? args[0] : this._rootNodeID; var isRender = fnName === '_renderValidatedComponent'; var entry = ReactDefaultPerf._allMeasurements[ ReactDefaultPerf._allMeasurements.length - 1 ]; if (isRender) { entry.counts[rootNodeID] = entry.counts[rootNodeID] || 0; entry.counts[rootNodeID] += 1; } start = performanceNow(); rv = func.apply(this, args); totalTime = performanceNow() - start; var typeOfLog = isRender ? entry.exclusive : entry.inclusive; typeOfLog[rootNodeID] = typeOfLog[rootNodeID] || 0; typeOfLog[rootNodeID] += totalTime; entry.displayNames[rootNodeID] = { current: this.constructor.displayName, owner: this._owner ? this._owner.constructor.displayName : '<root>' }; return rv; } else { return func.apply(this, args); } }; }
};
module.exports = ReactDefaultPerf;
},{“./DOMProperty”:9,“./ReactDefaultPerfAnalysis”:50,“./ReactMount”:60,“./ReactPerf”:65,“./performanceNow”:142}],50:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactDefaultPerfAnalysis */
var merge = dereq(“./merge”);
// Don't try to save users less than 1.2ms (a number I made up) var DONT_CARE_THRESHOLD = 1.2; var DOM_OPERATION_TYPES = {
'mountImageIntoNode': 'set innerHTML', INSERT_MARKUP: 'set innerHTML', MOVE_EXISTING: 'move', REMOVE_NODE: 'remove', TEXT_CONTENT: 'set textContent', 'updatePropertyByID': 'update attribute', 'deletePropertyByID': 'delete attribute', 'updateStylesByID': 'update styles', 'updateInnerHTMLByID': 'set innerHTML', 'dangerouslyReplaceNodeWithMarkupByID': 'replace'
};
function getTotalTime(measurements) {
// TODO: return number of DOM ops? could be misleading. // TODO: measure dropped frames after reconcile? // TODO: log total time of each reconcile and the top-level component // class that triggered it. var totalTime = 0; for (var i = 0; i < measurements.length; i++) { var measurement = measurements[i]; totalTime += measurement.totalTime; } return totalTime;
}
function getDOMSummary(measurements) {
var items = []; for (var i = 0; i < measurements.length; i++) { var measurement = measurements[i]; var id; for (id in measurement.writes) { measurement.writes[id].forEach(function(write) { items.push({ id: id, type: DOM_OPERATION_TYPES[write.type] || write.type, args: write.args }); }); } } return items;
}
function getExclusiveSummary(measurements) {
var candidates = {}; var displayName; for (var i = 0; i < measurements.length; i++) { var measurement = measurements[i]; var allIDs = merge(measurement.exclusive, measurement.inclusive); for (var id in allIDs) { displayName = measurement.displayNames[id].current; candidates[displayName] = candidates[displayName] || { componentName: displayName, inclusive: 0, exclusive: 0, count: 0 }; if (measurement.exclusive[id]) { candidates[displayName].exclusive += measurement.exclusive[id]; } if (measurement.inclusive[id]) { candidates[displayName].inclusive += measurement.inclusive[id]; } if (measurement.counts[id]) { candidates[displayName].count += measurement.counts[id]; } } } // Now make a sorted array with the results. var arr = []; for (displayName in candidates) { if (candidates[displayName].exclusive >= DONT_CARE_THRESHOLD) { arr.push(candidates[displayName]); } } arr.sort(function(a, b) { return b.exclusive - a.exclusive; }); return arr;
}
function getInclusiveSummary(measurements, onlyClean) {
var candidates = {}; var inclusiveKey; for (var i = 0; i < measurements.length; i++) { var measurement = measurements[i]; var allIDs = merge(measurement.exclusive, measurement.inclusive); var cleanComponents; if (onlyClean) { cleanComponents = getUnchangedComponents(measurement); } for (var id in allIDs) { if (onlyClean && !cleanComponents[id]) { continue; } var displayName = measurement.displayNames[id]; // Inclusive time is not useful for many components without knowing where // they are instantiated. So we aggregate inclusive time with both the // owner and current displayName as the key. inclusiveKey = displayName.owner + ' > ' + displayName.current; candidates[inclusiveKey] = candidates[inclusiveKey] || { componentName: inclusiveKey, time: 0, count: 0 }; if (measurement.inclusive[id]) { candidates[inclusiveKey].time += measurement.inclusive[id]; } if (measurement.counts[id]) { candidates[inclusiveKey].count += measurement.counts[id]; } } } // Now make a sorted array with the results. var arr = []; for (inclusiveKey in candidates) { if (candidates[inclusiveKey].time >= DONT_CARE_THRESHOLD) { arr.push(candidates[inclusiveKey]); } } arr.sort(function(a, b) { return b.time - a.time; }); return arr;
}
function getUnchangedComponents(measurement) {
// For a given reconcile, look at which components did not actually // render anything to the DOM and return a mapping of their ID to // the amount of time it took to render the entire subtree. var cleanComponents = {}; var dirtyLeafIDs = Object.keys(measurement.writes); var allIDs = merge(measurement.exclusive, measurement.inclusive); for (var id in allIDs) { var isDirty = false; // For each component that rendered, see if a component that triggerd // a DOM op is in its subtree. for (var i = 0; i < dirtyLeafIDs.length; i++) { if (dirtyLeafIDs[i].indexOf(id) === 0) { isDirty = true; break; } } if (!isDirty && measurement.counts[id] > 0) { cleanComponents[id] = true; } } return cleanComponents;
}
var ReactDefaultPerfAnalysis = {
getExclusiveSummary: getExclusiveSummary, getInclusiveSummary: getInclusiveSummary, getDOMSummary: getDOMSummary, getTotalTime: getTotalTime
};
module.exports = ReactDefaultPerfAnalysis;
},{“./merge”:134}],51:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactErrorUtils * @typechecks */
“use strict”;
var ReactErrorUtils = {
/** * Creates a guarded version of a function. This is supposed to make debugging * of event handlers easier. To aid debugging with the browser's debugger, * this currently simply returns the original function. * * @param {function} func Function to be executed * @param {string} name The name of the guard * @return {function} */ guard: function(func, name) { return func; }
};
module.exports = ReactErrorUtils;
},{}],52:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactEventEmitter * @typechecks static-only */
“use strict”;
var EventConstants = dereq(“./EventConstants”); var EventListener = dereq(“./EventListener”); var EventPluginHub = dereq(“./EventPluginHub”); var EventPluginRegistry = dereq(“./EventPluginRegistry”); var ExecutionEnvironment = dereq(“./ExecutionEnvironment”); var ReactEventEmitterMixin = dereq(“./ReactEventEmitterMixin”); var ViewportMetrics = dereq(“./ViewportMetrics”);
var invariant = dereq(“./invariant”); var isEventSupported = dereq(“./isEventSupported”); var merge = dereq(“./merge”);
/**
* Summary of `ReactEventEmitter` event handling: * * - Top-level delegation is used to trap native browser events. We normalize * and de-duplicate events to account for browser quirks. * * - Forward these native events (with the associated top-level type used to * trap it) to `EventPluginHub`, which in turn will ask plugins if they want * to extract any synthetic events. * * - The `EventPluginHub` will then process each event by annotating them with * "dispatches", a sequence of listeners and IDs that care about that event. * * - The `EventPluginHub` then dispatches the events. * * Overview of React and the event system: * * . * +------------+ . * | DOM | . * +------------+ . +-----------+ * + . +--------+|SimpleEvent| * | . | |Plugin | * +-----|------+ . v +-----------+ * | | | . +--------------+ +------------+ * | +-----------.--->|EventPluginHub| | Event | * | | . | | +-----------+ | Propagators| * | ReactEvent | . | | |TapEvent | |------------| * | Emitter | . | |<---+|Plugin | |other plugin| * | | . | | +-----------+ | utilities | * | +-----------.--->| | +------------+ * | | | . +--------------+ * +-----|------+ . ^ +-----------+ * | . | |Enter/Leave| * + . +-------+|Plugin | * +-------------+ . +-----------+ * | application | . * |-------------| . * | | . * | | . * +-------------+ . * . * React Core . General Purpose Event Plugin System */
var alreadyListeningTo = {}; var isMonitoringScrollValue = false; var reactTopListenersCounter = 0;
// For events like 'submit' which don't consistently bubble (which we trap at a // lower node than `document`), binding at `document` would cause duplicate // events so we don't include them here var topEventMapping = {
topBlur: 'blur', topChange: 'change', topClick: 'click', topCompositionEnd: 'compositionend', topCompositionStart: 'compositionstart', topCompositionUpdate: 'compositionupdate', topContextMenu: 'contextmenu', topCopy: 'copy', topCut: 'cut', topDoubleClick: 'dblclick', topDrag: 'drag', topDragEnd: 'dragend', topDragEnter: 'dragenter', topDragExit: 'dragexit', topDragLeave: 'dragleave', topDragOver: 'dragover', topDragStart: 'dragstart', topDrop: 'drop', topFocus: 'focus', topInput: 'input', topKeyDown: 'keydown', topKeyPress: 'keypress', topKeyUp: 'keyup', topMouseDown: 'mousedown', topMouseMove: 'mousemove', topMouseOut: 'mouseout', topMouseOver: 'mouseover', topMouseUp: 'mouseup', topPaste: 'paste', topScroll: 'scroll', topSelectionChange: 'selectionchange', topTouchCancel: 'touchcancel', topTouchEnd: 'touchend', topTouchMove: 'touchmove', topTouchStart: 'touchstart', topWheel: 'wheel'
};
/**
* To ensure no conflicts with other potential React instances on the page */
var topListenersIDKey = “_reactListenersID” + String(Math.random()).slice(2);
function getListeningForDocument(mountAt) {
if (mountAt[topListenersIDKey] == null) { mountAt[topListenersIDKey] = reactTopListenersCounter++; alreadyListeningTo[mountAt[topListenersIDKey]] = {}; } return alreadyListeningTo[mountAt[topListenersIDKey]];
}
/**
* Traps top-level events by using event bubbling. * * @param {string} topLevelType Record from `EventConstants`. * @param {string} handlerBaseName Event name (e.g. "click"). * @param {DOMEventTarget} element Element on which to attach listener. * @internal */
function trapBubbledEvent(topLevelType, handlerBaseName, element) {
EventListener.listen( element, handlerBaseName, ReactEventEmitter.TopLevelCallbackCreator.createTopLevelCallback( topLevelType ) );
}
/**
* Traps a top-level event by using event capturing. * * @param {string} topLevelType Record from `EventConstants`. * @param {string} handlerBaseName Event name (e.g. "click"). * @param {DOMEventTarget} element Element on which to attach listener. * @internal */
function trapCapturedEvent(topLevelType, handlerBaseName, element) {
EventListener.capture( element, handlerBaseName, ReactEventEmitter.TopLevelCallbackCreator.createTopLevelCallback( topLevelType ) );
}
/**
* `ReactEventEmitter` is used to attach top-level event listeners. For example: * * ReactEventEmitter.putListener('myID', 'onClick', myFunction); * * This would allocate a "registration" of `('onClick', myFunction)` on 'myID'. * * @internal */
var ReactEventEmitter = merge(ReactEventEmitterMixin, {
/** * React references `ReactEventTopLevelCallback` using this property in order * to allow dependency injection. */ TopLevelCallbackCreator: null, injection: { /** * @param {function} TopLevelCallbackCreator */ injectTopLevelCallbackCreator: function(TopLevelCallbackCreator) { ReactEventEmitter.TopLevelCallbackCreator = TopLevelCallbackCreator; } }, /** * Sets whether or not any created callbacks should be enabled. * * @param {boolean} enabled True if callbacks should be enabled. */ setEnabled: function(enabled) { ("production" !== "development" ? invariant( ExecutionEnvironment.canUseDOM, 'setEnabled(...): Cannot toggle event listening in a Worker thread. ' + 'This is likely a bug in the framework. Please report immediately.' ) : invariant(ExecutionEnvironment.canUseDOM)); if (ReactEventEmitter.TopLevelCallbackCreator) { ReactEventEmitter.TopLevelCallbackCreator.setEnabled(enabled); } }, /** * @return {boolean} True if callbacks are enabled. */ isEnabled: function() { return !!( ReactEventEmitter.TopLevelCallbackCreator && ReactEventEmitter.TopLevelCallbackCreator.isEnabled() ); }, /** * We listen for bubbled touch events on the document object. * * Firefox v8.01 (and possibly others) exhibited strange behavior when * mounting `onmousemove` events at some node that was not the document * element. The symptoms were that if your mouse is not moving over something * contained within that mount point (for example on the background) the * top-level listeners for `onmousemove` won't be called. However, if you * register the `mousemove` on the document object, then it will of course * catch all `mousemove`s. This along with iOS quirks, justifies restricting * top-level listeners to the document object only, at least for these * movement types of events and possibly all events. * * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html * * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but * they bubble to document. * * @param {string} registrationName Name of listener (e.g. `onClick`). * @param {DOMDocument} contentDocument Document which owns the container */ listenTo: function(registrationName, contentDocument) { var mountAt = contentDocument; var isListening = getListeningForDocument(mountAt); var dependencies = EventPluginRegistry. registrationNameDependencies[registrationName]; var topLevelTypes = EventConstants.topLevelTypes; for (var i = 0, l = dependencies.length; i < l; i++) { var dependency = dependencies[i]; if (!isListening[dependency]) { var topLevelType = topLevelTypes[dependency]; if (topLevelType === topLevelTypes.topWheel) { if (isEventSupported('wheel')) { trapBubbledEvent(topLevelTypes.topWheel, 'wheel', mountAt); } else if (isEventSupported('mousewheel')) { trapBubbledEvent(topLevelTypes.topWheel, 'mousewheel', mountAt); } else { // Firefox needs to capture a different mouse scroll event. // @see http://www.quirksmode.org/dom/events/tests/scroll.html trapBubbledEvent( topLevelTypes.topWheel, 'DOMMouseScroll', mountAt); } } else if (topLevelType === topLevelTypes.topScroll) { if (isEventSupported('scroll', true)) { trapCapturedEvent(topLevelTypes.topScroll, 'scroll', mountAt); } else { trapBubbledEvent(topLevelTypes.topScroll, 'scroll', window); } } else if (topLevelType === topLevelTypes.topFocus || topLevelType === topLevelTypes.topBlur) { if (isEventSupported('focus', true)) { trapCapturedEvent(topLevelTypes.topFocus, 'focus', mountAt); trapCapturedEvent(topLevelTypes.topBlur, 'blur', mountAt); } else if (isEventSupported('focusin')) { // IE has `focusin` and `focusout` events which bubble. // @see http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html trapBubbledEvent(topLevelTypes.topFocus, 'focusin', mountAt); trapBubbledEvent(topLevelTypes.topBlur, 'focusout', mountAt); } // to make sure blur and focus event listeners are only attached once isListening[topLevelTypes.topBlur] = true; isListening[topLevelTypes.topFocus] = true; } else if (topEventMapping[dependency]) { trapBubbledEvent(topLevelType, topEventMapping[dependency], mountAt); } isListening[dependency] = true; } } }, /** * Listens to window scroll and resize events. We cache scroll values so that * application code can access them without triggering reflows. * * NOTE: Scroll events do not bubble. * * @see http://www.quirksmode.org/dom/events/scroll.html */ ensureScrollValueMonitoring: function(){ if (!isMonitoringScrollValue) { var refresh = ViewportMetrics.refreshScrollValues; EventListener.listen(window, 'scroll', refresh); EventListener.listen(window, 'resize', refresh); isMonitoringScrollValue = true; } }, eventNameDispatchConfigs: EventPluginHub.eventNameDispatchConfigs, registrationNameModules: EventPluginHub.registrationNameModules, putListener: EventPluginHub.putListener, getListener: EventPluginHub.getListener, deleteListener: EventPluginHub.deleteListener, deleteAllListeners: EventPluginHub.deleteAllListeners, trapBubbledEvent: trapBubbledEvent, trapCapturedEvent: trapCapturedEvent
});
module.exports = ReactEventEmitter;
},{“./EventConstants”:15,“./EventListener”:16,“./EventPluginHub”:17,“./EventPluginRegistry”:18,“./ExecutionEnvironment”:21,“./ReactEventEmitterMixin”:53,“./ViewportMetrics”:97,“./invariant”:125,“./isEventSupported”:126,“./merge”:134}],53:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactEventEmitterMixin */
“use strict”;
var EventPluginHub = dereq(“./EventPluginHub”); var ReactUpdates = dereq(“./ReactUpdates”);
function runEventQueueInBatch(events) {
EventPluginHub.enqueueEvents(events); EventPluginHub.processEventQueue();
}
var ReactEventEmitterMixin = {
/** * Streams a fired top-level event to `EventPluginHub` where plugins have the * opportunity to create `ReactEvent`s to be dispatched. * * @param {string} topLevelType Record from `EventConstants`. * @param {object} topLevelTarget The listening component root node. * @param {string} topLevelTargetID ID of `topLevelTarget`. * @param {object} nativeEvent Native environment event. */ handleTopLevel: function( topLevelType, topLevelTarget, topLevelTargetID, nativeEvent) { var events = EventPluginHub.extractEvents( topLevelType, topLevelTarget, topLevelTargetID, nativeEvent ); // Event queue being processed in the same cycle allows `preventDefault`. ReactUpdates.batchedUpdates(runEventQueueInBatch, events); }
};
module.exports = ReactEventEmitterMixin;
},{“./EventPluginHub”:17,“./ReactUpdates”:81}],54:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactEventTopLevelCallback * @typechecks static-only */
“use strict”;
var PooledClass = dereq(“./PooledClass”); var ReactEventEmitter = dereq(“./ReactEventEmitter”); var ReactInstanceHandles = dereq(“./ReactInstanceHandles”); var ReactMount = dereq(“./ReactMount”);
var getEventTarget = dereq(“./getEventTarget”); var mixInto = dereq(“./mixInto”);
/**
* @type {boolean} * @private */
var _topLevelListenersEnabled = true;
/**
* Finds the parent React component of `node`. * * @param {*} node * @return {?DOMEventTarget} Parent container, or `null` if the specified node * is not nested. */
function findParent(node) {
// TODO: It may be a good idea to cache this to prevent unnecessary DOM // traversal, but caching is difficult to do correctly without using a // mutation observer to listen for all DOM changes. var nodeID = ReactMount.getID(node); var rootID = ReactInstanceHandles.getReactRootIDFromNodeID(nodeID); var container = ReactMount.findReactContainerForID(rootID); var parent = ReactMount.getFirstReactDOM(container); return parent;
}
/**
* Calls ReactEventEmitter.handleTopLevel for each node stored in bookKeeping's * ancestor list. Separated from createTopLevelCallback to avoid try/finally * deoptimization. * * @param {string} topLevelType * @param {DOMEvent} nativeEvent * @param {TopLevelCallbackBookKeeping} bookKeeping */
function handleTopLevelImpl(topLevelType, nativeEvent, bookKeeping) {
var topLevelTarget = ReactMount.getFirstReactDOM( getEventTarget(nativeEvent) ) || window; // Loop through the hierarchy, in case there's any nested components. // It's important that we build the array of ancestors before calling any // event handlers, because event handlers can modify the DOM, leading to // inconsistencies with ReactMount's node cache. See #1105. var ancestor = topLevelTarget; while (ancestor) { bookKeeping.ancestors.push(ancestor); ancestor = findParent(ancestor); } for (var i = 0, l = bookKeeping.ancestors.length; i < l; i++) { topLevelTarget = bookKeeping.ancestors[i]; var topLevelTargetID = ReactMount.getID(topLevelTarget) || ''; ReactEventEmitter.handleTopLevel( topLevelType, topLevelTarget, topLevelTargetID, nativeEvent ); }
}
// Used to store ancestor hierarchy in top level callback function TopLevelCallbackBookKeeping() {
this.ancestors = [];
} mixInto(TopLevelCallbackBookKeeping, {
destructor: function() { this.ancestors.length = 0; }
}); PooledClass.addPoolingTo(TopLevelCallbackBookKeeping);
/**
* Top-level callback creator used to implement event handling using delegation. * This is used via dependency injection. */
var ReactEventTopLevelCallback = {
/** * Sets whether or not any created callbacks should be enabled. * * @param {boolean} enabled True if callbacks should be enabled. */ setEnabled: function(enabled) { _topLevelListenersEnabled = !!enabled; }, /** * @return {boolean} True if callbacks are enabled. */ isEnabled: function() { return _topLevelListenersEnabled; }, /** * Creates a callback for the supplied `topLevelType` that could be added as * a listener to the document. The callback computes a `topLevelTarget` which * should be the root node of a mounted React component where the listener * is attached. * * @param {string} topLevelType Record from `EventConstants`. * @return {function} Callback for handling top-level events. */ createTopLevelCallback: function(topLevelType) { return function(nativeEvent) { if (!_topLevelListenersEnabled) { return; } var bookKeeping = TopLevelCallbackBookKeeping.getPooled(); try { handleTopLevelImpl(topLevelType, nativeEvent, bookKeeping); } finally { TopLevelCallbackBookKeeping.release(bookKeeping); } }; }
};
module.exports = ReactEventTopLevelCallback;
},{“./PooledClass”:25,“./ReactEventEmitter”:52,“./ReactInstanceHandles”:57,“./ReactMount”:60,“./getEventTarget”:117,“./mixInto”:137}],55:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactInjection */
“use strict”;
var DOMProperty = dereq(“./DOMProperty”); var EventPluginHub = dereq(“./EventPluginHub”); var ReactComponent = dereq(“./ReactComponent”); var ReactCompositeComponent = dereq(“./ReactCompositeComponent”); var ReactDOM = dereq(“./ReactDOM”); var ReactEventEmitter = dereq(“./ReactEventEmitter”); var ReactPerf = dereq(“./ReactPerf”); var ReactRootIndex = dereq(“./ReactRootIndex”); var ReactUpdates = dereq(“./ReactUpdates”);
var ReactInjection = {
Component: ReactComponent.injection, CompositeComponent: ReactCompositeComponent.injection, DOMProperty: DOMProperty.injection, EventPluginHub: EventPluginHub.injection, DOM: ReactDOM.injection, EventEmitter: ReactEventEmitter.injection, Perf: ReactPerf.injection, RootIndex: ReactRootIndex.injection, Updates: ReactUpdates.injection
};
module.exports = ReactInjection;
},{“./DOMProperty”:9,“./EventPluginHub”:17,“./ReactComponent”:31,“./ReactCompositeComponent”:33,“./ReactDOM”:36,“./ReactEventEmitter”:52,“./ReactPerf”:65,“./ReactRootIndex”:72,“./ReactUpdates”:81}],56:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactInputSelection */
“use strict”;
var ReactDOMSelection = dereq(“./ReactDOMSelection”);
var containsNode = dereq(“./containsNode”); var focusNode = dereq(“./focusNode”); var getActiveElement = dereq(“./getActiveElement”);
function isInDocument(node) {
return containsNode(document.documentElement, node);
}
/**
* @ReactInputSelection: React input selection module. Based on Selection.js, * but modified to be suitable for react and has a couple of bug fixes (doesn't * assume buttons have range selections allowed). * Input selection module for React. */
var ReactInputSelection = {
hasSelectionCapabilities: function(elem) { return elem && ( (elem.nodeName === 'INPUT' && elem.type === 'text') || elem.nodeName === 'TEXTAREA' || elem.contentEditable === 'true' ); }, getSelectionInformation: function() { var focusedElem = getActiveElement(); return { focusedElem: focusedElem, selectionRange: ReactInputSelection.hasSelectionCapabilities(focusedElem) ? ReactInputSelection.getSelection(focusedElem) : null }; }, /** * @restoreSelection: If any selection information was potentially lost, * restore it. This is useful when performing operations that could remove dom * nodes and place them back in, resulting in focus being lost. */ restoreSelection: function(priorSelectionInformation) { var curFocusedElem = getActiveElement(); var priorFocusedElem = priorSelectionInformation.focusedElem; var priorSelectionRange = priorSelectionInformation.selectionRange; if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) { if (ReactInputSelection.hasSelectionCapabilities(priorFocusedElem)) { ReactInputSelection.setSelection( priorFocusedElem, priorSelectionRange ); } focusNode(priorFocusedElem); } }, /** * @getSelection: Gets the selection bounds of a focused textarea, input or * contentEditable node. * -@input: Look up selection bounds of this input * -@return {start: selectionStart, end: selectionEnd} */ getSelection: function(input) { var selection; if ('selectionStart' in input) { // Modern browser with input or textarea. selection = { start: input.selectionStart, end: input.selectionEnd }; } else if (document.selection && input.nodeName === 'INPUT') { // IE8 input. var range = document.selection.createRange(); // There can only be one selection per document in IE, so it must // be in our element. if (range.parentElement() === input) { selection = { start: -range.moveStart('character', -input.value.length), end: -range.moveEnd('character', -input.value.length) }; } } else { // Content editable or old IE textarea. selection = ReactDOMSelection.getOffsets(input); } return selection || {start: 0, end: 0}; }, /** * @setSelection: Sets the selection bounds of a textarea or input and focuses * the input. * -@input Set selection bounds of this input or textarea * -@offsets Object of same form that is returned from get* */ setSelection: function(input, offsets) { var start = offsets.start; var end = offsets.end; if (typeof end === 'undefined') { end = start; } if ('selectionStart' in input) { input.selectionStart = start; input.selectionEnd = Math.min(end, input.value.length); } else if (document.selection && input.nodeName === 'INPUT') { var range = input.createTextRange(); range.collapse(true); range.moveStart('character', start); range.moveEnd('character', end - start); range.select(); } else { ReactDOMSelection.setOffsets(input, offsets); } }
};
module.exports = ReactInputSelection;
},{“./ReactDOMSelection”:45,“./containsNode”:101,“./focusNode”:113,“./getActiveElement”:115}],57:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactInstanceHandles * @typechecks static-only */
“use strict”;
var ReactRootIndex = dereq(“./ReactRootIndex”);
var invariant = dereq(“./invariant”);
var SEPARATOR = '.'; var SEPARATOR_LENGTH = SEPARATOR.length;
/**
* Maximum depth of traversals before we consider the possibility of a bad ID. */
var MAX_TREE_DEPTH = 100;
/**
* Creates a DOM ID prefix to use when mounting React components. * * @param {number} index A unique integer * @return {string} React root ID. * @internal */
function getReactRootIDString(index) {
return SEPARATOR + index.toString(36);
}
/**
* Checks if a character in the supplied ID is a separator or the end. * * @param {string} id A React DOM ID. * @param {number} index Index of the character to check. * @return {boolean} True if the character is a separator or end of the ID. * @private */
function isBoundary(id, index) {
return id.charAt(index) === SEPARATOR || index === id.length;
}
/**
* Checks if the supplied string is a valid React DOM ID. * * @param {string} id A React DOM ID, maybe. * @return {boolean} True if the string is a valid React DOM ID. * @private */
function isValidID(id) {
return id === '' || ( id.charAt(0) === SEPARATOR && id.charAt(id.length - 1) !== SEPARATOR );
}
/**
* Checks if the first ID is an ancestor of or equal to the second ID. * * @param {string} ancestorID * @param {string} descendantID * @return {boolean} True if `ancestorID` is an ancestor of `descendantID`. * @internal */
function isAncestorIDOf(ancestorID, descendantID) {
return ( descendantID.indexOf(ancestorID) === 0 && isBoundary(descendantID, ancestorID.length) );
}
/**
* Gets the parent ID of the supplied React DOM ID, `id`. * * @param {string} id ID of a component. * @return {string} ID of the parent, or an empty string. * @private */
function getParentID(id) {
return id ? id.substr(0, id.lastIndexOf(SEPARATOR)) : '';
}
/**
* Gets the next DOM ID on the tree path from the supplied `ancestorID` to the * supplied `destinationID`. If they are equal, the ID is returned. * * @param {string} ancestorID ID of an ancestor node of `destinationID`. * @param {string} destinationID ID of the destination node. * @return {string} Next ID on the path from `ancestorID` to `destinationID`. * @private */
function getNextDescendantID(ancestorID, destinationID) {
("production" !== "development" ? invariant( isValidID(ancestorID) && isValidID(destinationID), 'getNextDescendantID(%s, %s): Received an invalid React DOM ID.', ancestorID, destinationID ) : invariant(isValidID(ancestorID) && isValidID(destinationID))); ("production" !== "development" ? invariant( isAncestorIDOf(ancestorID, destinationID), 'getNextDescendantID(...): React has made an invalid assumption about ' + 'the DOM hierarchy. Expected `%s` to be an ancestor of `%s`.', ancestorID, destinationID ) : invariant(isAncestorIDOf(ancestorID, destinationID))); if (ancestorID === destinationID) { return ancestorID; } // Skip over the ancestor and the immediate separator. Traverse until we hit // another separator or we reach the end of `destinationID`. var start = ancestorID.length + SEPARATOR_LENGTH; for (var i = start; i < destinationID.length; i++) { if (isBoundary(destinationID, i)) { break; } } return destinationID.substr(0, i);
}
/**
* Gets the nearest common ancestor ID of two IDs. * * Using this ID scheme, the nearest common ancestor ID is the longest common * prefix of the two IDs that immediately preceded a "marker" in both strings. * * @param {string} oneID * @param {string} twoID * @return {string} Nearest common ancestor ID, or the empty string if none. * @private */
function getFirstCommonAncestorID(oneID, twoID) {
var minLength = Math.min(oneID.length, twoID.length); if (minLength === 0) { return ''; } var lastCommonMarkerIndex = 0; // Use `<=` to traverse until the "EOL" of the shorter string. for (var i = 0; i <= minLength; i++) { if (isBoundary(oneID, i) && isBoundary(twoID, i)) { lastCommonMarkerIndex = i; } else if (oneID.charAt(i) !== twoID.charAt(i)) { break; } } var longestCommonID = oneID.substr(0, lastCommonMarkerIndex); ("production" !== "development" ? invariant( isValidID(longestCommonID), 'getFirstCommonAncestorID(%s, %s): Expected a valid React DOM ID: %s', oneID, twoID, longestCommonID ) : invariant(isValidID(longestCommonID))); return longestCommonID;
}
/**
* Traverses the parent path between two IDs (either up or down). The IDs must * not be the same, and there must exist a parent path between them. If the * callback returns `false`, traversal is stopped. * * @param {?string} start ID at which to start traversal. * @param {?string} stop ID at which to end traversal. * @param {function} cb Callback to invoke each ID with. * @param {?boolean} skipFirst Whether or not to skip the first node. * @param {?boolean} skipLast Whether or not to skip the last node. * @private */
function traverseParentPath(start, stop, cb, arg, skipFirst, skipLast) {
start = start || ''; stop = stop || ''; ("production" !== "development" ? invariant( start !== stop, 'traverseParentPath(...): Cannot traverse from and to the same ID, `%s`.', start ) : invariant(start !== stop)); var traverseUp = isAncestorIDOf(stop, start); ("production" !== "development" ? invariant( traverseUp || isAncestorIDOf(start, stop), 'traverseParentPath(%s, %s, ...): Cannot traverse from two IDs that do ' + 'not have a parent path.', start, stop ) : invariant(traverseUp || isAncestorIDOf(start, stop))); // Traverse from `start` to `stop` one depth at a time. var depth = 0; var traverse = traverseUp ? getParentID : getNextDescendantID; for (var id = start; /* until break */; id = traverse(id, stop)) { var ret; if ((!skipFirst || id !== start) && (!skipLast || id !== stop)) { ret = cb(id, traverseUp, arg); } if (ret === false || id === stop) { // Only break //after// visiting `stop`. break; } ("production" !== "development" ? invariant( depth++ < MAX_TREE_DEPTH, 'traverseParentPath(%s, %s, ...): Detected an infinite loop while ' + 'traversing the React DOM ID tree. This may be due to malformed IDs: %s', start, stop ) : invariant(depth++ < MAX_TREE_DEPTH)); }
}
/**
* Manages the IDs assigned to DOM representations of React components. This * uses a specific scheme in order to traverse the DOM efficiently (e.g. in * order to simulate events). * * @internal */
var ReactInstanceHandles = {
/** * Constructs a React root ID * @return {string} A React root ID. */ createReactRootID: function() { return getReactRootIDString(ReactRootIndex.createReactRootIndex()); }, /** * Constructs a React ID by joining a root ID with a name. * * @param {string} rootID Root ID of a parent component. * @param {string} name A component's name (as flattened children). * @return {string} A React ID. * @internal */ createReactID: function(rootID, name) { return rootID + name; }, /** * Gets the DOM ID of the React component that is the root of the tree that * contains the React component with the supplied DOM ID. * * @param {string} id DOM ID of a React component. * @return {?string} DOM ID of the React component that is the root. * @internal */ getReactRootIDFromNodeID: function(id) { if (id && id.charAt(0) === SEPARATOR && id.length > 1) { var index = id.indexOf(SEPARATOR, 1); return index > -1 ? id.substr(0, index) : id; } return null; }, /** * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that * should would receive a `mouseEnter` or `mouseLeave` event. * * NOTE: Does not invoke the callback on the nearest common ancestor because * nothing "entered" or "left" that element. * * @param {string} leaveID ID being left. * @param {string} enterID ID being entered. * @param {function} cb Callback to invoke on each entered/left ID. * @param {*} upArg Argument to invoke the callback with on left IDs. * @param {*} downArg Argument to invoke the callback with on entered IDs. * @internal */ traverseEnterLeave: function(leaveID, enterID, cb, upArg, downArg) { var ancestorID = getFirstCommonAncestorID(leaveID, enterID); if (ancestorID !== leaveID) { traverseParentPath(leaveID, ancestorID, cb, upArg, false, true); } if (ancestorID !== enterID) { traverseParentPath(ancestorID, enterID, cb, downArg, true, false); } }, /** * Simulates the traversal of a two-phase, capture/bubble event dispatch. * * NOTE: This traversal happens on IDs without touching the DOM. * * @param {string} targetID ID of the target node. * @param {function} cb Callback to invoke. * @param {*} arg Argument to invoke the callback with. * @internal */ traverseTwoPhase: function(targetID, cb, arg) { if (targetID) { traverseParentPath('', targetID, cb, arg, true, false); traverseParentPath(targetID, '', cb, arg, false, true); } }, /** * Traverse a node ID, calling the supplied `cb` for each ancestor ID. For * example, passing `.0.$row-0.1` would result in `cb` getting called * with `.0`, `.0.$row-0`, and `.0.$row-0.1`. * * NOTE: This traversal happens on IDs without touching the DOM. * * @param {string} targetID ID of the target node. * @param {function} cb Callback to invoke. * @param {*} arg Argument to invoke the callback with. * @internal */ traverseAncestors: function(targetID, cb, arg) { traverseParentPath('', targetID, cb, arg, true, false); }, /** * Exposed for unit testing. * @private */ _getFirstCommonAncestorID: getFirstCommonAncestorID, /** * Exposed for unit testing. * @private */ _getNextDescendantID: getNextDescendantID, isAncestorIDOf: isAncestorIDOf, SEPARATOR: SEPARATOR
};
module.exports = ReactInstanceHandles;
},{“./ReactRootIndex”:72,“./invariant”:125}],58:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactLink * @typechecks static-only */
“use strict”;
/**
* ReactLink encapsulates a common pattern in which a component wants to modify * a prop received from its parent. ReactLink allows the parent to pass down a * value coupled with a callback that, when invoked, expresses an intent to * modify that value. For example: * * React.createClass({ * getInitialState: function() { * return {value: ''}; * }, * render: function() { * var valueLink = new ReactLink(this.state.value, this._handleValueChange); * return <input valueLink={valueLink} />; * }, * this._handleValueChange: function(newValue) { * this.setState({value: newValue}); * } * }); * * We have provided some sugary mixins to make the creation and * consumption of ReactLink easier; see LinkedValueUtils and LinkedStateMixin. */
/**
* @param {*} value current value of the link * @param {function} requestChange callback to request a change */
function ReactLink(value, requestChange) {
this.value = value; this.requestChange = requestChange;
}
module.exports = ReactLink;
},{}],59:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactMarkupChecksum */
“use strict”;
var adler32 = dereq(“./adler32”);
var ReactMarkupChecksum = {
CHECKSUM_ATTR_NAME: 'data-react-checksum', /** * @param {string} markup Markup string * @return {string} Markup string with checksum attribute attached */ addChecksumToMarkup: function(markup) { var checksum = adler32(markup); return markup.replace( '>', ' ' + ReactMarkupChecksum.CHECKSUM_ATTR_NAME + '="' + checksum + '">' ); }, /** * @param {string} markup to use * @param {DOMElement} element root React element * @returns {boolean} whether or not the markup is the same */ canReuseMarkup: function(markup, element) { var existingChecksum = element.getAttribute( ReactMarkupChecksum.CHECKSUM_ATTR_NAME ); existingChecksum = existingChecksum && parseInt(existingChecksum, 10); var markupChecksum = adler32(markup); return markupChecksum === existingChecksum; }
};
module.exports = ReactMarkupChecksum;
},{“./adler32”:99}],60:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactMount */
“use strict”;
var DOMProperty = dereq(“./DOMProperty”); var ReactEventEmitter = dereq(“./ReactEventEmitter”); var ReactInstanceHandles = dereq(“./ReactInstanceHandles”); var ReactPerf = dereq(“./ReactPerf”);
var containsNode = dereq(“./containsNode”); var getReactRootElementInContainer = dereq(“./getReactRootElementInContainer”); var instantiateReactComponent = dereq(“./instantiateReactComponent”); var invariant = dereq(“./invariant”); var shouldUpdateReactComponent = dereq(“./shouldUpdateReactComponent”);
var SEPARATOR = ReactInstanceHandles.SEPARATOR;
var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME; var nodeCache = {};
var ELEMENT_NODE_TYPE = 1; var DOC_NODE_TYPE = 9;
/** Mapping from reactRootID to React component instance. */ var instancesByReactRootID = {};
/** Mapping from reactRootID to `container` nodes. */ var containersByReactRootID = {};
if (“production” !== “development”) {
/** __DEV__-only mapping from reactRootID to root elements. */ var rootElementsByReactRootID = {};
}
// Used to store breadth-first search state in findComponentRoot. var findComponentRootReusableArray = [];
/**
* @param {DOMElement} container DOM element that may contain a React component. * @return {?string} A "reactRoot" ID, if a React component is rendered. */
function getReactRootID(container) {
var rootElement = getReactRootElementInContainer(container); return rootElement && ReactMount.getID(rootElement);
}
/**
* Accessing node[ATTR_NAME] or calling getAttribute(ATTR_NAME) on a form * element can return its control whose name or ID equals ATTR_NAME. All * DOM nodes support `getAttributeNode` but this can also get called on * other objects so just return '' if we're given something other than a * DOM node (such as window). * * @param {?DOMElement|DOMWindow|DOMDocument|DOMTextNode} node DOM node. * @return {string} ID of the supplied `domNode`. */
function getID(node) {
var id = internalGetID(node); if (id) { if (nodeCache.hasOwnProperty(id)) { var cached = nodeCache[id]; if (cached !== node) { ("production" !== "development" ? invariant( !isValid(cached, id), 'ReactMount: Two valid but unequal nodes with the same `%s`: %s', ATTR_NAME, id ) : invariant(!isValid(cached, id))); nodeCache[id] = node; } } else { nodeCache[id] = node; } } return id;
}
function internalGetID(node) {
// If node is something like a window, document, or text node, none of // which support attributes or a .getAttribute method, gracefully return // the empty string, as if the attribute were missing. return node && node.getAttribute && node.getAttribute(ATTR_NAME) || '';
}
/**
* Sets the React-specific ID of the given node. * * @param {DOMElement} node The DOM node whose ID will be set. * @param {string} id The value of the ID attribute. */
function setID(node, id) {
var oldID = internalGetID(node); if (oldID !== id) { delete nodeCache[oldID]; } node.setAttribute(ATTR_NAME, id); nodeCache[id] = node;
}
/**
* Finds the node with the supplied React-generated DOM ID. * * @param {string} id A React-generated DOM ID. * @return {DOMElement} DOM node with the suppled `id`. * @internal */
function getNode(id) {
if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) { nodeCache[id] = ReactMount.findReactNodeByID(id); } return nodeCache[id];
}
/**
* A node is "valid" if it is contained by a currently mounted container. * * This means that the node does not have to be contained by a document in * order to be considered valid. * * @param {?DOMElement} node The candidate DOM node. * @param {string} id The expected ID of the node. * @return {boolean} Whether the node is contained by a mounted container. */
function isValid(node, id) {
if (node) { ("production" !== "development" ? invariant( internalGetID(node) === id, 'ReactMount: Unexpected modification of `%s`', ATTR_NAME ) : invariant(internalGetID(node) === id)); var container = ReactMount.findReactContainerForID(id); if (container && containsNode(container, node)) { return true; } } return false;
}
/**
* Causes the cache to forget about one React-specific ID. * * @param {string} id The ID to forget. */
function purgeID(id) {
delete nodeCache[id];
}
var deepestNodeSoFar = null; function findDeepestCachedAncestorImpl(ancestorID) {
var ancestor = nodeCache[ancestorID]; if (ancestor && isValid(ancestor, ancestorID)) { deepestNodeSoFar = ancestor; } else { // This node isn't populated in the cache, so presumably none of its // descendants are. Break out of the loop. return false; }
}
/**
* Return the deepest cached node whose ID is a prefix of `targetID`. */
function findDeepestCachedAncestor(targetID) {
deepestNodeSoFar = null; ReactInstanceHandles.traverseAncestors( targetID, findDeepestCachedAncestorImpl ); var foundNode = deepestNodeSoFar; deepestNodeSoFar = null; return foundNode;
}
/**
* Mounting is the process of initializing a React component by creatings its * representative DOM elements and inserting them into a supplied `container`. * Any prior content inside `container` is destroyed in the process. * * ReactMount.renderComponent( * component, * document.getElementById('container') * ); * * <div id="container"> <-- Supplied `container`. * <div data-reactid=".3"> <-- Rendered reactRoot of React * // ... component. * </div> * </div> * * Inside of `container`, the first element rendered is the "reactRoot". */
var ReactMount = {
/** Time spent generating markup. */ totalInstantiationTime: 0, /** Time spent inserting markup into the DOM. */ totalInjectionTime: 0, /** Whether support for touch events should be initialized. */ useTouchEvents: false, /** Exposed for debugging purposes **/ _instancesByReactRootID: instancesByReactRootID, /** * This is a hook provided to support rendering React components while * ensuring that the apparent scroll position of its `container` does not * change. * * @param {DOMElement} container The `container` being rendered into. * @param {function} renderCallback This must be called once to do the render. */ scrollMonitor: function(container, renderCallback) { renderCallback(); }, /** * Take a component that's already mounted into the DOM and replace its props * @param {ReactComponent} prevComponent component instance already in the DOM * @param {ReactComponent} nextComponent component instance to render * @param {DOMElement} container container to render into * @param {?function} callback function triggered on completion */ _updateRootComponent: function( prevComponent, nextComponent, container, callback) { var nextProps = nextComponent.props; ReactMount.scrollMonitor(container, function() { prevComponent.replaceProps(nextProps, callback); }); if ("production" !== "development") { // Record the root element in case it later gets transplanted. rootElementsByReactRootID[getReactRootID(container)] = getReactRootElementInContainer(container); } return prevComponent; }, /** * Register a component into the instance map and starts scroll value * monitoring * @param {ReactComponent} nextComponent component instance to render * @param {DOMElement} container container to render into * @return {string} reactRoot ID prefix */ _registerComponent: function(nextComponent, container) { ("production" !== "development" ? invariant( container && ( container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE ), '_registerComponent(...): Target container is not a DOM element.' ) : invariant(container && ( container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE ))); ReactEventEmitter.ensureScrollValueMonitoring(); var reactRootID = ReactMount.registerContainer(container); instancesByReactRootID[reactRootID] = nextComponent; return reactRootID; }, /** * Render a new component into the DOM. * @param {ReactComponent} nextComponent component instance to render * @param {DOMElement} container container to render into * @param {boolean} shouldReuseMarkup if we should skip the markup insertion * @return {ReactComponent} nextComponent */ _renderNewRootComponent: ReactPerf.measure( 'ReactMount', '_renderNewRootComponent', function( nextComponent, container, shouldReuseMarkup) { var componentInstance = instantiateReactComponent(nextComponent); var reactRootID = ReactMount._registerComponent( componentInstance, container ); componentInstance.mountComponentIntoNode( reactRootID, container, shouldReuseMarkup ); if ("production" !== "development") { // Record the root element in case it later gets transplanted. rootElementsByReactRootID[reactRootID] = getReactRootElementInContainer(container); } return componentInstance; } ), /** * Renders a React component into the DOM in the supplied `container`. * * If the React component was previously rendered into `container`, this will * perform an update on it and only mutate the DOM as necessary to reflect the * latest React component. * * @param {ReactComponent} nextComponent Component instance to render. * @param {DOMElement} container DOM element to render into. * @param {?function} callback function triggered on completion * @return {ReactComponent} Component instance rendered in `container`. */ renderComponent: function(nextComponent, container, callback) { var prevComponent = instancesByReactRootID[getReactRootID(container)]; if (prevComponent) { if (shouldUpdateReactComponent(prevComponent, nextComponent)) { return ReactMount._updateRootComponent( prevComponent, nextComponent, container, callback ); } else { ReactMount.unmountComponentAtNode(container); } } var reactRootElement = getReactRootElementInContainer(container); var containerHasReactMarkup = reactRootElement && ReactMount.isRenderedByReact(reactRootElement); var shouldReuseMarkup = containerHasReactMarkup && !prevComponent; var component = ReactMount._renderNewRootComponent( nextComponent, container, shouldReuseMarkup ); callback && callback.call(component); return component; }, /** * Constructs a component instance of `constructor` with `initialProps` and * renders it into the supplied `container`. * * @param {function} constructor React component constructor. * @param {?object} props Initial props of the component instance. * @param {DOMElement} container DOM element to render into. * @return {ReactComponent} Component instance rendered in `container`. */ constructAndRenderComponent: function(constructor, props, container) { return ReactMount.renderComponent(constructor(props), container); }, /** * Constructs a component instance of `constructor` with `initialProps` and * renders it into a container node identified by supplied `id`. * * @param {function} componentConstructor React component constructor * @param {?object} props Initial props of the component instance. * @param {string} id ID of the DOM element to render into. * @return {ReactComponent} Component instance rendered in the container node. */ constructAndRenderComponentByID: function(constructor, props, id) { var domNode = document.getElementById(id); ("production" !== "development" ? invariant( domNode, 'Tried to get element with id of "%s" but it is not present on the page.', id ) : invariant(domNode)); return ReactMount.constructAndRenderComponent(constructor, props, domNode); }, /** * Registers a container node into which React components will be rendered. * This also creates the "reactRoot" ID that will be assigned to the element * rendered within. * * @param {DOMElement} container DOM element to register as a container. * @return {string} The "reactRoot" ID of elements rendered within. */ registerContainer: function(container) { var reactRootID = getReactRootID(container); if (reactRootID) { // If one exists, make sure it is a valid "reactRoot" ID. reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(reactRootID); } if (!reactRootID) { // No valid "reactRoot" ID found, create one. reactRootID = ReactInstanceHandles.createReactRootID(); } containersByReactRootID[reactRootID] = container; return reactRootID; }, /** * Unmounts and destroys the React component rendered in the `container`. * * @param {DOMElement} container DOM element containing a React component. * @return {boolean} True if a component was found in and unmounted from * `container` */ unmountComponentAtNode: function(container) { var reactRootID = getReactRootID(container); var component = instancesByReactRootID[reactRootID]; if (!component) { return false; } ReactMount.unmountComponentFromNode(component, container); delete instancesByReactRootID[reactRootID]; delete containersByReactRootID[reactRootID]; if ("production" !== "development") { delete rootElementsByReactRootID[reactRootID]; } return true; }, /** * Unmounts a component and removes it from the DOM. * * @param {ReactComponent} instance React component instance. * @param {DOMElement} container DOM element to unmount from. * @final * @internal * @see {ReactMount.unmountComponentAtNode} */ unmountComponentFromNode: function(instance, container) { instance.unmountComponent(); if (container.nodeType === DOC_NODE_TYPE) { container = container.documentElement; } // http://jsperf.com/emptying-a-node while (container.lastChild) { container.removeChild(container.lastChild); } }, /** * Finds the container DOM element that contains React component to which the * supplied DOM `id` belongs. * * @param {string} id The ID of an element rendered by a React component. * @return {?DOMElement} DOM element that contains the `id`. */ findReactContainerForID: function(id) { var reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(id); var container = containersByReactRootID[reactRootID]; if ("production" !== "development") { var rootElement = rootElementsByReactRootID[reactRootID]; if (rootElement && rootElement.parentNode !== container) { ("production" !== "development" ? invariant( // Call internalGetID here because getID calls isValid which calls // findReactContainerForID (this function). internalGetID(rootElement) === reactRootID, 'ReactMount: Root element ID differed from reactRootID.' ) : invariant(// Call internalGetID here because getID calls isValid which calls // findReactContainerForID (this function). internalGetID(rootElement) === reactRootID)); var containerChild = container.firstChild; if (containerChild && reactRootID === internalGetID(containerChild)) { // If the container has a new child with the same ID as the old // root element, then rootElementsByReactRootID[reactRootID] is // just stale and needs to be updated. The case that deserves a // warning is when the container is empty. rootElementsByReactRootID[reactRootID] = containerChild; } else { console.warn( 'ReactMount: Root element has been removed from its original ' + 'container. New container:', rootElement.parentNode ); } } } return container; }, /** * Finds an element rendered by React with the supplied ID. * * @param {string} id ID of a DOM node in the React component. * @return {DOMElement} Root DOM node of the React component. */ findReactNodeByID: function(id) { var reactRoot = ReactMount.findReactContainerForID(id); return ReactMount.findComponentRoot(reactRoot, id); }, /** * True if the supplied `node` is rendered by React. * * @param {*} node DOM Element to check. * @return {boolean} True if the DOM Element appears to be rendered by React. * @internal */ isRenderedByReact: function(node) { if (node.nodeType !== 1) { // Not a DOMElement, therefore not a React component return false; } var id = ReactMount.getID(node); return id ? id.charAt(0) === SEPARATOR : false; }, /** * Traverses up the ancestors of the supplied node to find a node that is a * DOM representation of a React component. * * @param {*} node * @return {?DOMEventTarget} * @internal */ getFirstReactDOM: function(node) { var current = node; while (current && current.parentNode !== current) { if (ReactMount.isRenderedByReact(current)) { return current; } current = current.parentNode; } return null; }, /** * Finds a node with the supplied `targetID` inside of the supplied * `ancestorNode`. Exploits the ID naming scheme to perform the search * quickly. * * @param {DOMEventTarget} ancestorNode Search from this root. * @pararm {string} targetID ID of the DOM representation of the component. * @return {DOMEventTarget} DOM node with the supplied `targetID`. * @internal */ findComponentRoot: function(ancestorNode, targetID) { var firstChildren = findComponentRootReusableArray; var childIndex = 0; var deepestAncestor = findDeepestCachedAncestor(targetID) || ancestorNode; firstChildren[0] = deepestAncestor.firstChild; firstChildren.length = 1; while (childIndex < firstChildren.length) { var child = firstChildren[childIndex++]; var targetChild; while (child) { var childID = ReactMount.getID(child); if (childID) { // Even if we find the node we're looking for, we finish looping // through its siblings to ensure they're cached so that we don't have // to revisit this node again. Otherwise, we make n^2 calls to getID // when visiting the many children of a single node in order. if (targetID === childID) { targetChild = child; } else if (ReactInstanceHandles.isAncestorIDOf(childID, targetID)) { // If we find a child whose ID is an ancestor of the given ID, // then we can be sure that we only want to search the subtree // rooted at this child, so we can throw out the rest of the // search state. firstChildren.length = childIndex = 0; firstChildren.push(child.firstChild); } } else { // If this child had no ID, then there's a chance that it was // injected automatically by the browser, as when a `<table>` // element sprouts an extra `<tbody>` child as a side effect of // `.innerHTML` parsing. Optimistically continue down this // branch, but not before examining the other siblings. firstChildren.push(child.firstChild); } child = child.nextSibling; } if (targetChild) { // Emptying firstChildren/findComponentRootReusableArray is // not necessary for correctness, but it helps the GC reclaim // any nodes that were left at the end of the search. firstChildren.length = 0; return targetChild; } } firstChildren.length = 0; ("production" !== "development" ? invariant( false, 'findComponentRoot(..., %s): Unable to find element. This probably ' + 'means the DOM was unexpectedly mutated (e.g., by the browser), ' + 'usually due to forgetting a <tbody> when using tables or nesting <p> ' + 'or <a> tags. Try inspecting the child nodes of the element with React ' + 'ID `%s`.', targetID, ReactMount.getID(ancestorNode) ) : invariant(false)); }, /** * React ID utilities. */ getReactRootID: getReactRootID, getID: getID, setID: setID, getNode: getNode, purgeID: purgeID
};
module.exports = ReactMount;
},{“./DOMProperty”:9,“./ReactEventEmitter”:52,“./ReactInstanceHandles”:57,“./ReactPerf”:65,“./containsNode”:101,“./getReactRootElementInContainer”:120,“./instantiateReactComponent”:124,“./invariant”:125,“./shouldUpdateReactComponent”:144}],61:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactMountReady */
“use strict”;
var PooledClass = dereq(“./PooledClass”);
var mixInto = dereq(“./mixInto”);
/**
* A specialized pseudo-event module to help keep track of components waiting to * be notified when their DOM representations are available for use. * * This implements `PooledClass`, so you should never need to instantiate this. * Instead, use `ReactMountReady.getPooled()`. * * @param {?array<function>} initialCollection * @class ReactMountReady * @implements PooledClass * @internal */
function ReactMountReady(initialCollection) {
this._queue = initialCollection || null;
}
mixInto(ReactMountReady, {
/** * Enqueues a callback to be invoked when `notifyAll` is invoked. This is used * to enqueue calls to `componentDidMount` and `componentDidUpdate`. * * @param {ReactComponent} component Component being rendered. * @param {function(DOMElement)} callback Invoked when `notifyAll` is invoked. * @internal */ enqueue: function(component, callback) { this._queue = this._queue || []; this._queue.push({component: component, callback: callback}); }, /** * Invokes all enqueued callbacks and clears the queue. This is invoked after * the DOM representation of a component has been created or updated. * * @internal */ notifyAll: function() { var queue = this._queue; if (queue) { this._queue = null; for (var i = 0, l = queue.length; i < l; i++) { var component = queue[i].component; var callback = queue[i].callback; callback.call(component); } queue.length = 0; } }, /** * Resets the internal queue. * * @internal */ reset: function() { this._queue = null; }, /** * `PooledClass` looks for this. */ destructor: function() { this.reset(); }
});
PooledClass.addPoolingTo(ReactMountReady);
module.exports = ReactMountReady;
},{“./PooledClass”:25,“./mixInto”:137}],62:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactMultiChild * @typechecks static-only */
“use strict”;
var ReactComponent = dereq(“./ReactComponent”); var ReactMultiChildUpdateTypes = dereq(“./ReactMultiChildUpdateTypes”);
var flattenChildren = dereq(“./flattenChildren”); var instantiateReactComponent = dereq(“./instantiateReactComponent”); var shouldUpdateReactComponent = dereq(“./shouldUpdateReactComponent”);
/**
* Updating children of a component may trigger recursive updates. The depth is * used to batch recursive updates to render markup more efficiently. * * @type {number} * @private */
var updateDepth = 0;
/**
* Queue of update configuration objects. * * Each object has a `type` property that is in `ReactMultiChildUpdateTypes`. * * @type {array<object>} * @private */
var updateQueue = [];
/**
* Queue of markup to be rendered. * * @type {array<string>} * @private */
var markupQueue = [];
/**
* Enqueues markup to be rendered and inserted at a supplied index. * * @param {string} parentID ID of the parent component. * @param {string} markup Markup that renders into an element. * @param {number} toIndex Destination index. * @private */
function enqueueMarkup(parentID, markup, toIndex) {
// NOTE: Null values reduce hidden classes. updateQueue.push({ parentID: parentID, parentNode: null, type: ReactMultiChildUpdateTypes.INSERT_MARKUP, markupIndex: markupQueue.push(markup) - 1, textContent: null, fromIndex: null, toIndex: toIndex });
}
/**
* Enqueues moving an existing element to another index. * * @param {string} parentID ID of the parent component. * @param {number} fromIndex Source index of the existing element. * @param {number} toIndex Destination index of the element. * @private */
function enqueueMove(parentID, fromIndex, toIndex) {
// NOTE: Null values reduce hidden classes. updateQueue.push({ parentID: parentID, parentNode: null, type: ReactMultiChildUpdateTypes.MOVE_EXISTING, markupIndex: null, textContent: null, fromIndex: fromIndex, toIndex: toIndex });
}
/**
* Enqueues removing an element at an index. * * @param {string} parentID ID of the parent component. * @param {number} fromIndex Index of the element to remove. * @private */
function enqueueRemove(parentID, fromIndex) {
// NOTE: Null values reduce hidden classes. updateQueue.push({ parentID: parentID, parentNode: null, type: ReactMultiChildUpdateTypes.REMOVE_NODE, markupIndex: null, textContent: null, fromIndex: fromIndex, toIndex: null });
}
/**
* Enqueues setting the text content. * * @param {string} parentID ID of the parent component. * @param {string} textContent Text content to set. * @private */
function enqueueTextContent(parentID, textContent) {
// NOTE: Null values reduce hidden classes. updateQueue.push({ parentID: parentID, parentNode: null, type: ReactMultiChildUpdateTypes.TEXT_CONTENT, markupIndex: null, textContent: textContent, fromIndex: null, toIndex: null });
}
/**
* Processes any enqueued updates. * * @private */
function processQueue() {
if (updateQueue.length) { ReactComponent.BackendIDOperations.dangerouslyProcessChildrenUpdates( updateQueue, markupQueue ); clearQueue(); }
}
/**
* Clears any enqueued updates. * * @private */
function clearQueue() {
updateQueue.length = 0; markupQueue.length = 0;
}
/**
* ReactMultiChild are capable of reconciling multiple children. * * @class ReactMultiChild * @internal */
var ReactMultiChild = {
/** * Provides common functionality for components that must reconcile multiple * children. This is used by `ReactDOMComponent` to mount, update, and * unmount child components. * * @lends {ReactMultiChild.prototype} */ Mixin: { /** * Generates a "mount image" for each of the supplied children. In the case * of `ReactDOMComponent`, a mount image is a string of markup. * * @param {?object} nestedChildren Nested child maps. * @return {array} An array of mounted representations. * @internal */ mountChildren: function(nestedChildren, transaction) { var children = flattenChildren(nestedChildren); var mountImages = []; var index = 0; this._renderedChildren = children; for (var name in children) { var child = children[name]; if (children.hasOwnProperty(name)) { // The rendered children must be turned into instances as they're // mounted. var childInstance = instantiateReactComponent(child); children[name] = childInstance; // Inlined for performance, see `ReactInstanceHandles.createReactID`. var rootID = this._rootNodeID + name; var mountImage = childInstance.mountComponent( rootID, transaction, this._mountDepth + 1 ); childInstance._mountIndex = index; mountImages.push(mountImage); index++; } } return mountImages; }, /** * Replaces any rendered children with a text content string. * * @param {string} nextContent String of content. * @internal */ updateTextContent: function(nextContent) { updateDepth++; var errorThrown = true; try { var prevChildren = this._renderedChildren; // Remove any rendered children. for (var name in prevChildren) { if (prevChildren.hasOwnProperty(name)) { this._unmountChildByName(prevChildren[name], name); } } // Set new text content. this.setTextContent(nextContent); errorThrown = false; } finally { updateDepth--; if (!updateDepth) { errorThrown ? clearQueue() : processQueue(); } } }, /** * Updates the rendered children with new children. * * @param {?object} nextNestedChildren Nested child maps. * @param {ReactReconcileTransaction} transaction * @internal */ updateChildren: function(nextNestedChildren, transaction) { updateDepth++; var errorThrown = true; try { this._updateChildren(nextNestedChildren, transaction); errorThrown = false; } finally { updateDepth--; if (!updateDepth) { errorThrown ? clearQueue() : processQueue(); } } }, /** * Improve performance by isolating this hot code path from the try/catch * block in `updateChildren`. * * @param {?object} nextNestedChildren Nested child maps. * @param {ReactReconcileTransaction} transaction * @final * @protected */ _updateChildren: function(nextNestedChildren, transaction) { var nextChildren = flattenChildren(nextNestedChildren); var prevChildren = this._renderedChildren; if (!nextChildren && !prevChildren) { return; } var name; // `nextIndex` will increment for each child in `nextChildren`, but // `lastIndex` will be the last index visited in `prevChildren`. var lastIndex = 0; var nextIndex = 0; for (name in nextChildren) { if (!nextChildren.hasOwnProperty(name)) { continue; } var prevChild = prevChildren && prevChildren[name]; var nextChild = nextChildren[name]; if (shouldUpdateReactComponent(prevChild, nextChild)) { this.moveChild(prevChild, nextIndex, lastIndex); lastIndex = Math.max(prevChild._mountIndex, lastIndex); prevChild.receiveComponent(nextChild, transaction); prevChild._mountIndex = nextIndex; } else { if (prevChild) { // Update `lastIndex` before `_mountIndex` gets unset by unmounting. lastIndex = Math.max(prevChild._mountIndex, lastIndex); this._unmountChildByName(prevChild, name); } // The child must be instantiated before it's mounted. var nextChildInstance = instantiateReactComponent(nextChild); this._mountChildByNameAtIndex( nextChildInstance, name, nextIndex, transaction ); } nextIndex++; } // Remove children that are no longer present. for (name in prevChildren) { if (prevChildren.hasOwnProperty(name) && !(nextChildren && nextChildren[name])) { this._unmountChildByName(prevChildren[name], name); } } }, /** * Unmounts all rendered children. This should be used to clean up children * when this component is unmounted. * * @internal */ unmountChildren: function() { var renderedChildren = this._renderedChildren; for (var name in renderedChildren) { var renderedChild = renderedChildren[name]; // TODO: When is this not true? if (renderedChild.unmountComponent) { renderedChild.unmountComponent(); } } this._renderedChildren = null; }, /** * Moves a child component to the supplied index. * * @param {ReactComponent} child Component to move. * @param {number} toIndex Destination index of the element. * @param {number} lastIndex Last index visited of the siblings of `child`. * @protected */ moveChild: function(child, toIndex, lastIndex) { // If the index of `child` is less than `lastIndex`, then it needs to // be moved. Otherwise, we do not need to move it because a child will be // inserted or moved before `child`. if (child._mountIndex < lastIndex) { enqueueMove(this._rootNodeID, child._mountIndex, toIndex); } }, /** * Creates a child component. * * @param {ReactComponent} child Component to create. * @param {string} mountImage Markup to insert. * @protected */ createChild: function(child, mountImage) { enqueueMarkup(this._rootNodeID, mountImage, child._mountIndex); }, /** * Removes a child component. * * @param {ReactComponent} child Child to remove. * @protected */ removeChild: function(child) { enqueueRemove(this._rootNodeID, child._mountIndex); }, /** * Sets this text content string. * * @param {string} textContent Text content to set. * @protected */ setTextContent: function(textContent) { enqueueTextContent(this._rootNodeID, textContent); }, /** * Mounts a child with the supplied name. * * NOTE: This is part of `updateChildren` and is here for readability. * * @param {ReactComponent} child Component to mount. * @param {string} name Name of the child. * @param {number} index Index at which to insert the child. * @param {ReactReconcileTransaction} transaction * @private */ _mountChildByNameAtIndex: function(child, name, index, transaction) { // Inlined for performance, see `ReactInstanceHandles.createReactID`. var rootID = this._rootNodeID + name; var mountImage = child.mountComponent( rootID, transaction, this._mountDepth + 1 ); child._mountIndex = index; this.createChild(child, mountImage); this._renderedChildren = this._renderedChildren || {}; this._renderedChildren[name] = child; }, /** * Unmounts a rendered child by name. * * NOTE: This is part of `updateChildren` and is here for readability. * * @param {ReactComponent} child Component to unmount. * @param {string} name Name of the child in `this._renderedChildren`. * @private */ _unmountChildByName: function(child, name) { // TODO: When is this not true? if (ReactComponent.isValidComponent(child)) { this.removeChild(child); child._mountIndex = null; child.unmountComponent(); delete this._renderedChildren[name]; } } }
};
module.exports = ReactMultiChild;
},{“./ReactComponent”:31,“./ReactMultiChildUpdateTypes”:63,“./flattenChildren”:112,“./instantiateReactComponent”:124,“./shouldUpdateReactComponent”:144}],63:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactMultiChildUpdateTypes */
“use strict”;
var keyMirror = dereq(“./keyMirror”);
/**
* When a component's children are updated, a series of update configuration * objects are created in order to batch and serialize the required changes. * * Enumerates all the possible types of update configurations. * * @internal */
var ReactMultiChildUpdateTypes = keyMirror({
INSERT_MARKUP: null, MOVE_EXISTING: null, REMOVE_NODE: null, TEXT_CONTENT: null
});
module.exports = ReactMultiChildUpdateTypes;
},{“./keyMirror”:131}],64:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactOwner */
“use strict”;
var emptyObject = dereq(“./emptyObject”); var invariant = dereq(“./invariant”);
/**
* ReactOwners are capable of storing references to owned components. * * All components are capable of //being// referenced by owner components, but * only ReactOwner components are capable of //referencing// owned components. * The named reference is known as a "ref". * * Refs are available when mounted and updated during reconciliation. * * var MyComponent = React.createClass({ * render: function() { * return ( * <div onClick={this.handleClick}> * <CustomComponent ref="custom" /> * </div> * ); * }, * handleClick: function() { * this.refs.custom.handleClick(); * }, * componentDidMount: function() { * this.refs.custom.initialize(); * } * }); * * Refs should rarely be used. When refs are used, they should only be done to * control data that is not handled by React's data flow. * * @class ReactOwner */
var ReactOwner = {
/** * @param {?object} object * @return {boolean} True if `object` is a valid owner. * @final */ isValidOwner: function(object) { return !!( object && typeof object.attachRef === 'function' && typeof object.detachRef === 'function' ); }, /** * Adds a component by ref to an owner component. * * @param {ReactComponent} component Component to reference. * @param {string} ref Name by which to refer to the component. * @param {ReactOwner} owner Component on which to record the ref. * @final * @internal */ addComponentAsRefTo: function(component, ref, owner) { ("production" !== "development" ? invariant( ReactOwner.isValidOwner(owner), 'addComponentAsRefTo(...): Only a ReactOwner can have refs. This ' + 'usually means that you\'re trying to add a ref to a component that ' + 'doesn\'t have an owner (that is, was not created inside of another ' + 'component\'s `render` method). Try rendering this component inside of ' + 'a new top-level component which will hold the ref.' ) : invariant(ReactOwner.isValidOwner(owner))); owner.attachRef(ref, component); }, /** * Removes a component by ref from an owner component. * * @param {ReactComponent} component Component to dereference. * @param {string} ref Name of the ref to remove. * @param {ReactOwner} owner Component on which the ref is recorded. * @final * @internal */ removeComponentAsRefFrom: function(component, ref, owner) { ("production" !== "development" ? invariant( ReactOwner.isValidOwner(owner), 'removeComponentAsRefFrom(...): Only a ReactOwner can have refs. This ' + 'usually means that you\'re trying to remove a ref to a component that ' + 'doesn\'t have an owner (that is, was not created inside of another ' + 'component\'s `render` method). Try rendering this component inside of ' + 'a new top-level component which will hold the ref.' ) : invariant(ReactOwner.isValidOwner(owner))); // Check that `component` is still the current ref because we do not want to // detach the ref if another component stole it. if (owner.refs[ref] === component) { owner.detachRef(ref); } }, /** * A ReactComponent must mix this in to have refs. * * @lends {ReactOwner.prototype} */ Mixin: { construct: function() { this.refs = emptyObject; }, /** * Lazily allocates the refs object and stores `component` as `ref`. * * @param {string} ref Reference name. * @param {component} component Component to store as `ref`. * @final * @private */ attachRef: function(ref, component) { ("production" !== "development" ? invariant( component.isOwnedBy(this), 'attachRef(%s, ...): Only a component\'s owner can store a ref to it.', ref ) : invariant(component.isOwnedBy(this))); var refs = this.refs === emptyObject ? (this.refs = {}) : this.refs; refs[ref] = component; }, /** * Detaches a reference name. * * @param {string} ref Name to dereference. * @final * @private */ detachRef: function(ref) { delete this.refs[ref]; } }
};
module.exports = ReactOwner;
},{“./emptyObject”:110,“./invariant”:125}],65:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactPerf * @typechecks static-only */
“use strict”;
/**
* ReactPerf is a general AOP system designed to measure performance. This * module only has the hooks: see ReactDefaultPerf for the analysis tool. */
var ReactPerf = {
/** * Boolean to enable/disable measurement. Set to false by default to prevent * accidental logging and perf loss. */ enableMeasure: false, /** * Holds onto the measure function in use. By default, don't measure * anything, but we'll override this if we inject a measure function. */ storedMeasure: _noMeasure, /** * Use this to wrap methods you want to measure. Zero overhead in production. * * @param {string} objName * @param {string} fnName * @param {function} func * @return {function} */ measure: function(objName, fnName, func) { if ("production" !== "development") { var measuredFunc = null; return function() { if (ReactPerf.enableMeasure) { if (!measuredFunc) { measuredFunc = ReactPerf.storedMeasure(objName, fnName, func); } return measuredFunc.apply(this, arguments); } return func.apply(this, arguments); }; } return func; }, injection: { /** * @param {function} measure */ injectMeasure: function(measure) { ReactPerf.storedMeasure = measure; } }
};
/**
* Simply passes through the measured function, without measuring it. * * @param {string} objName * @param {string} fnName * @param {function} func * @return {function} */
function _noMeasure(objName, fnName, func) {
return func;
}
module.exports = ReactPerf;
},{}],66:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactPropTransferer */
“use strict”;
var emptyFunction = dereq(“./emptyFunction”); var invariant = dereq(“./invariant”); var joinClasses = dereq(“./joinClasses”); var merge = dereq(“./merge”);
/**
* Creates a transfer strategy that will merge prop values using the supplied * `mergeStrategy`. If a prop was previously unset, this just sets it. * * @param {function} mergeStrategy * @return {function} */
function createTransferStrategy(mergeStrategy) {
return function(props, key, value) { if (!props.hasOwnProperty(key)) { props[key] = value; } else { props[key] = mergeStrategy(props[key], value); } };
}
/**
* Transfer strategies dictate how props are transferred by `transferPropsTo`. * NOTE: if you add any more exceptions to this list you should be sure to * update `cloneWithProps()` accordingly. */
var TransferStrategies = {
/** * Never transfer `children`. */ children: emptyFunction, /** * Transfer the `className` prop by merging them. */ className: createTransferStrategy(joinClasses), /** * Never transfer the `key` prop. */ key: emptyFunction, /** * Never transfer the `ref` prop. */ ref: emptyFunction, /** * Transfer the `style` prop (which is an object) by merging them. */ style: createTransferStrategy(merge)
};
/**
* ReactPropTransferer are capable of transferring props to another component * using a `transferPropsTo` method. * * @class ReactPropTransferer */
var ReactPropTransferer = {
TransferStrategies: TransferStrategies, /** * Merge two props objects using TransferStrategies. * * @param {object} oldProps original props (they take precedence) * @param {object} newProps new props to merge in * @return {object} a new object containing both sets of props merged. */ mergeProps: function(oldProps, newProps) { var props = merge(oldProps); for (var thisKey in newProps) { if (!newProps.hasOwnProperty(thisKey)) { continue; } var transferStrategy = TransferStrategies[thisKey]; if (transferStrategy && TransferStrategies.hasOwnProperty(thisKey)) { transferStrategy(props, thisKey, newProps[thisKey]); } else if (!props.hasOwnProperty(thisKey)) { props[thisKey] = newProps[thisKey]; } } return props; }, /** * @lends {ReactPropTransferer.prototype} */ Mixin: { /** * Transfer props from this component to a target component. * * Props that do not have an explicit transfer strategy will be transferred * only if the target component does not already have the prop set. * * This is usually used to pass down props to a returned root component. * * @param {ReactComponent} component Component receiving the properties. * @return {ReactComponent} The supplied `component`. * @final * @protected */ transferPropsTo: function(component) { ("production" !== "development" ? invariant( component._owner === this, '%s: You can\'t call transferPropsTo() on a component that you ' + 'don\'t own, %s. This usually means you are calling ' + 'transferPropsTo() on a component passed in as props or children.', this.constructor.displayName, component.constructor.displayName ) : invariant(component._owner === this)); component.props = ReactPropTransferer.mergeProps( component.props, this.props ); return component; } }
};
module.exports = ReactPropTransferer;
},{“./emptyFunction”:109,“./invariant”:125,“./joinClasses”:130,“./merge”:134}],67:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactPropTypeLocationNames */
“use strict”;
var ReactPropTypeLocationNames = {};
if (“production” !== “development”) {
ReactPropTypeLocationNames = { prop: 'prop', context: 'context', childContext: 'child context' };
}
module.exports = ReactPropTypeLocationNames;
},{}],68:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactPropTypeLocations */
“use strict”;
var keyMirror = dereq(“./keyMirror”);
var ReactPropTypeLocations = keyMirror({
prop: null, context: null, childContext: null
});
module.exports = ReactPropTypeLocations;
},{“./keyMirror”:131}],69:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactPropTypes */
“use strict”;
var ReactComponent = dereq(“./ReactComponent”); var ReactPropTypeLocationNames = dereq(“./ReactPropTypeLocationNames”);
var warning = dereq(“./warning”); var createObjectFrom = dereq(“./createObjectFrom”);
/**
* Collection of methods that allow declaration and validation of props that are * supplied to React components. Example usage: * * var Props = require('ReactPropTypes'); * var MyArticle = React.createClass({ * propTypes: { * // An optional string prop named "description". * description: Props.string, * * // A required enum prop named "category". * category: Props.oneOf(['News','Photos']).isRequired, * * // A prop named "dialog" that requires an instance of Dialog. * dialog: Props.instanceOf(Dialog).isRequired * }, * render: function() { ... } * }); * * A more formal specification of how these methods are used: * * type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...) * decl := ReactPropTypes.{type}(.isRequired)? * * Each and every declaration produces a function with the same signature. This * allows the creation of custom validation functions. For example: * * var Props = require('ReactPropTypes'); * var MyLink = React.createClass({ * propTypes: { * // An optional string or URI prop named "href". * href: function(props, propName, componentName) { * var propValue = props[propName]; * warning( * propValue == null || * typeof propValue === 'string' || * propValue instanceof URI, * 'Invalid `%s` supplied to `%s`, expected string or URI.', * propName, * componentName * ); * } * }, * render: function() { ... } * }); * * @internal */
var Props = {
array: createPrimitiveTypeChecker('array'), bool: createPrimitiveTypeChecker('boolean'), func: createPrimitiveTypeChecker('function'), number: createPrimitiveTypeChecker('number'), object: createPrimitiveTypeChecker('object'), string: createPrimitiveTypeChecker('string'), shape: createShapeTypeChecker, oneOf: createEnumTypeChecker, oneOfType: createUnionTypeChecker, arrayOf: createArrayOfTypeChecker, instanceOf: createInstanceTypeChecker, renderable: createRenderableTypeChecker(), component: createComponentTypeChecker(), any: createAnyTypeChecker()
};
var ANONYMOUS = '<<anonymous>>';
function isRenderable(propValue) {
switch(typeof propValue) { case 'number': case 'string': return true; case 'object': if (Array.isArray(propValue)) { return propValue.every(isRenderable); } if (ReactComponent.isValidComponent(propValue)) { return true; } for (var k in propValue) { if (!isRenderable(propValue[k])) { return false; } } return true; default: return false; }
}
// Equivalent of typeof but with special handling for arrays function getPropType(propValue) {
var propType = typeof propValue; if (propType === 'object' && Array.isArray(propValue)) { return 'array'; } return propType;
}
function createAnyTypeChecker() {
function validateAnyType( shouldWarn, propValue, propName, componentName, location ) { return true; // is always valid } return createChainableTypeChecker(validateAnyType);
}
function createPrimitiveTypeChecker(expectedType) {
function validatePrimitiveType( shouldWarn, propValue, propName, componentName, location ) { var propType = getPropType(propValue); var isValid = propType === expectedType; if (shouldWarn) { ("production" !== "development" ? warning( isValid, 'Invalid %s `%s` of type `%s` supplied to `%s`, expected `%s`.', ReactPropTypeLocationNames[location], propName, propType, componentName, expectedType ) : null); } return isValid; } return createChainableTypeChecker(validatePrimitiveType);
}
function createEnumTypeChecker(expectedValues) {
var expectedEnum = createObjectFrom(expectedValues); function validateEnumType( shouldWarn, propValue, propName, componentName, location ) { var isValid = expectedEnum[propValue]; if (shouldWarn) { ("production" !== "development" ? warning( isValid, 'Invalid %s `%s` supplied to `%s`, expected one of %s.', ReactPropTypeLocationNames[location], propName, componentName, JSON.stringify(Object.keys(expectedEnum)) ) : null); } return isValid; } return createChainableTypeChecker(validateEnumType);
}
function createShapeTypeChecker(shapeTypes) {
function validateShapeType( shouldWarn, propValue, propName, componentName, location ) { var propType = getPropType(propValue); var isValid = propType === 'object'; if (isValid) { for (var key in shapeTypes) { var checker = shapeTypes[key]; if (checker && !checker(propValue, key, componentName, location)) { return false; } } } if (shouldWarn) { ("production" !== "development" ? warning( isValid, 'Invalid %s `%s` of type `%s` supplied to `%s`, expected `object`.', ReactPropTypeLocationNames[location], propName, propType, componentName ) : null); } return isValid; } return createChainableTypeChecker(validateShapeType);
}
function createInstanceTypeChecker(expectedClass) {
function validateInstanceType( shouldWarn, propValue, propName, componentName, location ) { var isValid = propValue instanceof expectedClass; if (shouldWarn) { ("production" !== "development" ? warning( isValid, 'Invalid %s `%s` supplied to `%s`, expected instance of `%s`.', ReactPropTypeLocationNames[location], propName, componentName, expectedClass.name || ANONYMOUS ) : null); } return isValid; } return createChainableTypeChecker(validateInstanceType);
}
function createArrayOfTypeChecker(propTypeChecker) {
function validateArrayType( shouldWarn, propValue, propName, componentName, location ) { var isValid = Array.isArray(propValue); if (isValid) { for (var i = 0; i < propValue.length; i++) { if (!propTypeChecker(propValue, i, componentName, location)) { return false; } } } if (shouldWarn) { ("production" !== "development" ? warning( isValid, 'Invalid %s `%s` supplied to `%s`, expected an array.', ReactPropTypeLocationNames[location], propName, componentName ) : null); } return isValid; } return createChainableTypeChecker(validateArrayType);
}
function createRenderableTypeChecker() {
function validateRenderableType( shouldWarn, propValue, propName, componentName, location ) { var isValid = isRenderable(propValue); if (shouldWarn) { ("production" !== "development" ? warning( isValid, 'Invalid %s `%s` supplied to `%s`, expected a renderable prop.', ReactPropTypeLocationNames[location], propName, componentName ) : null); } return isValid; } return createChainableTypeChecker(validateRenderableType);
}
function createComponentTypeChecker() {
function validateComponentType( shouldWarn, propValue, propName, componentName, location ) { var isValid = ReactComponent.isValidComponent(propValue); if (shouldWarn) { ("production" !== "development" ? warning( isValid, 'Invalid %s `%s` supplied to `%s`, expected a React component.', ReactPropTypeLocationNames[location], propName, componentName ) : null); } return isValid; } return createChainableTypeChecker(validateComponentType);
}
function createUnionTypeChecker(arrayOfValidators) {
return function(props, propName, componentName, location) { var isValid = false; for (var ii = 0; ii < arrayOfValidators.length; ii++) { var validate = arrayOfValidators[ii]; if (typeof validate.weak === 'function') { validate = validate.weak; } if (validate(props, propName, componentName, location)) { isValid = true; break; } } ("production" !== "development" ? warning( isValid, 'Invalid %s `%s` supplied to `%s`.', ReactPropTypeLocationNames[location], propName, componentName || ANONYMOUS ) : null); return isValid; };
}
function createChainableTypeChecker(validate) {
function checkType( isRequired, shouldWarn, props, propName, componentName, location ) { var propValue = props[propName]; if (propValue != null) { // Only validate if there is a value to check. return validate( shouldWarn, propValue, propName, componentName || ANONYMOUS, location ); } else { var isValid = !isRequired; if (shouldWarn) { ("production" !== "development" ? warning( isValid, 'Required %s `%s` was not specified in `%s`.', ReactPropTypeLocationNames[location], propName, componentName || ANONYMOUS ) : null); } return isValid; } } var checker = checkType.bind(null, false, true); checker.weak = checkType.bind(null, false, false); checker.isRequired = checkType.bind(null, true, true); checker.weak.isRequired = checkType.bind(null, true, false); checker.isRequired.weak = checker.weak.isRequired; return checker;
}
module.exports = Props;
},{“./ReactComponent”:31,“./ReactPropTypeLocationNames”:67,“./createObjectFrom”:106,“./warning”:148}],70:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactPutListenerQueue */
“use strict”;
var PooledClass = dereq(“./PooledClass”); var ReactEventEmitter = dereq(“./ReactEventEmitter”);
var mixInto = dereq(“./mixInto”);
function ReactPutListenerQueue() {
this.listenersToPut = [];
}
mixInto(ReactPutListenerQueue, {
enqueuePutListener: function(rootNodeID, propKey, propValue) { this.listenersToPut.push({ rootNodeID: rootNodeID, propKey: propKey, propValue: propValue }); }, putListeners: function() { for (var i = 0; i < this.listenersToPut.length; i++) { var listenerToPut = this.listenersToPut[i]; ReactEventEmitter.putListener( listenerToPut.rootNodeID, listenerToPut.propKey, listenerToPut.propValue ); } }, reset: function() { this.listenersToPut.length = 0; }, destructor: function() { this.reset(); }
});
PooledClass.addPoolingTo(ReactPutListenerQueue);
module.exports = ReactPutListenerQueue;
},{“./PooledClass”:25,“./ReactEventEmitter”:52,“./mixInto”:137}],71:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactReconcileTransaction * @typechecks static-only */
“use strict”;
var PooledClass = dereq(“./PooledClass”); var ReactEventEmitter = dereq(“./ReactEventEmitter”); var ReactInputSelection = dereq(“./ReactInputSelection”); var ReactMountReady = dereq(“./ReactMountReady”); var ReactPutListenerQueue = dereq(“./ReactPutListenerQueue”); var Transaction = dereq(“./Transaction”);
var mixInto = dereq(“./mixInto”);
/**
* Ensures that, when possible, the selection range (currently selected text * input) is not disturbed by performing the transaction. */
var SELECTION_RESTORATION = {
/** * @return {Selection} Selection information. */ initialize: ReactInputSelection.getSelectionInformation, /** * @param {Selection} sel Selection information returned from `initialize`. */ close: ReactInputSelection.restoreSelection
};
/**
* Suppresses events (blur/focus) that could be inadvertently dispatched due to * high level DOM manipulations (like temporarily removing a text input from the * DOM). */
var EVENT_SUPPRESSION = {
/** * @return {boolean} The enabled status of `ReactEventEmitter` before the * reconciliation. */ initialize: function() { var currentlyEnabled = ReactEventEmitter.isEnabled(); ReactEventEmitter.setEnabled(false); return currentlyEnabled; }, /** * @param {boolean} previouslyEnabled Enabled status of `ReactEventEmitter` * before the reconciliation occured. `close` restores the previous value. */ close: function(previouslyEnabled) { ReactEventEmitter.setEnabled(previouslyEnabled); }
};
/**
* Provides a `ReactMountReady` queue for collecting `onDOMReady` callbacks * during the performing of the transaction. */
var ON_DOM_READY_QUEUEING = {
/** * Initializes the internal `onDOMReady` queue. */ initialize: function() { this.reactMountReady.reset(); }, /** * After DOM is flushed, invoke all registered `onDOMReady` callbacks. */ close: function() { this.reactMountReady.notifyAll(); }
};
var PUT_LISTENER_QUEUEING = {
initialize: function() { this.putListenerQueue.reset(); }, close: function() { this.putListenerQueue.putListeners(); }
};
/**
* Executed within the scope of the `Transaction` instance. Consider these as * being member methods, but with an implied ordering while being isolated from * each other. */
var TRANSACTION_WRAPPERS = [
PUT_LISTENER_QUEUEING, SELECTION_RESTORATION, EVENT_SUPPRESSION, ON_DOM_READY_QUEUEING
];
/**
* Currently: * - The order that these are listed in the transaction is critical: * - Suppresses events. * - Restores selection range. * * Future: * - Restore document/overflow scroll positions that were unintentionally * modified via DOM insertions above the top viewport boundary. * - Implement/integrate with customized constraint based layout system and keep * track of which dimensions must be remeasured. * * @class ReactReconcileTransaction */
function ReactReconcileTransaction() {
this.reinitializeTransaction(); // Only server-side rendering really needs this option (see // `ReactServerRendering`), but server-side uses // `ReactServerRenderingTransaction` instead. This option is here so that it's // accessible and defaults to false when `ReactDOMComponent` and // `ReactTextComponent` checks it in `mountComponent`.` this.renderToStaticMarkup = false; this.reactMountReady = ReactMountReady.getPooled(null); this.putListenerQueue = ReactPutListenerQueue.getPooled();
}
var Mixin = {
/** * @see Transaction * @abstract * @final * @return {array<object>} List of operation wrap proceedures. * TODO: convert to array<TransactionWrapper> */ getTransactionWrappers: function() { return TRANSACTION_WRAPPERS; }, /** * @return {object} The queue to collect `onDOMReady` callbacks with. * TODO: convert to ReactMountReady */ getReactMountReady: function() { return this.reactMountReady; }, getPutListenerQueue: function() { return this.putListenerQueue; }, /** * `PooledClass` looks for this, and will invoke this before allowing this * instance to be resused. */ destructor: function() { ReactMountReady.release(this.reactMountReady); this.reactMountReady = null; ReactPutListenerQueue.release(this.putListenerQueue); this.putListenerQueue = null; }
};
mixInto(ReactReconcileTransaction, Transaction.Mixin); mixInto(ReactReconcileTransaction, Mixin);
PooledClass.addPoolingTo(ReactReconcileTransaction);
module.exports = ReactReconcileTransaction;
},{“./PooledClass”:25,“./ReactEventEmitter”:52,“./ReactInputSelection”:56,“./ReactMountReady”:61,“./ReactPutListenerQueue”:70,“./Transaction”:96,“./mixInto”:137}],72:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactRootIndex * @typechecks */
“use strict”;
var ReactRootIndexInjection = {
/** * @param {function} _createReactRootIndex */ injectCreateReactRootIndex: function(_createReactRootIndex) { ReactRootIndex.createReactRootIndex = _createReactRootIndex; }
};
var ReactRootIndex = {
createReactRootIndex: null, injection: ReactRootIndexInjection
};
module.exports = ReactRootIndex;
},{}],73:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @typechecks static-only * @providesModule ReactServerRendering */
“use strict”;
var ReactComponent = dereq(“./ReactComponent”); var ReactInstanceHandles = dereq(“./ReactInstanceHandles”); var ReactMarkupChecksum = dereq(“./ReactMarkupChecksum”); var ReactServerRenderingTransaction =
_dereq_("./ReactServerRenderingTransaction");
var instantiateReactComponent = dereq(“./instantiateReactComponent”); var invariant = dereq(“./invariant”);
/**
* @param {ReactComponent} component * @return {string} the HTML markup */
function renderComponentToString(component) {
("production" !== "development" ? invariant( ReactComponent.isValidComponent(component), 'renderComponentToString(): You must pass a valid ReactComponent.' ) : invariant(ReactComponent.isValidComponent(component))); ("production" !== "development" ? invariant( !(arguments.length === 2 && typeof arguments[1] === 'function'), 'renderComponentToString(): This function became synchronous and now ' + 'returns the generated markup. Please remove the second parameter.' ) : invariant(!(arguments.length === 2 && typeof arguments[1] === 'function'))); var transaction; try { var id = ReactInstanceHandles.createReactRootID(); transaction = ReactServerRenderingTransaction.getPooled(false); return transaction.perform(function() { var componentInstance = instantiateReactComponent(component); var markup = componentInstance.mountComponent(id, transaction, 0); return ReactMarkupChecksum.addChecksumToMarkup(markup); }, null); } finally { ReactServerRenderingTransaction.release(transaction); }
}
/**
* @param {ReactComponent} component * @return {string} the HTML markup, without the extra React ID and checksum
-
(for generating static pages)
*/
function renderComponentToStaticMarkup(component) {
("production" !== "development" ? invariant( ReactComponent.isValidComponent(component), 'renderComponentToStaticMarkup(): You must pass a valid ReactComponent.' ) : invariant(ReactComponent.isValidComponent(component))); var transaction; try { var id = ReactInstanceHandles.createReactRootID(); transaction = ReactServerRenderingTransaction.getPooled(true); return transaction.perform(function() { var componentInstance = instantiateReactComponent(component); return componentInstance.mountComponent(id, transaction, 0); }, null); } finally { ReactServerRenderingTransaction.release(transaction); }
}
module.exports = {
renderComponentToString: renderComponentToString, renderComponentToStaticMarkup: renderComponentToStaticMarkup
};
},{“./ReactComponent”:31,“./ReactInstanceHandles”:57,“./ReactMarkupChecksum”:59,“./ReactServerRenderingTransaction”:74,“./instantiateReactComponent”:124,“./invariant”:125}],74:[function(dereq,module,exports){ /**
* Copyright 2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactServerRenderingTransaction * @typechecks */
“use strict”;
var PooledClass = dereq(“./PooledClass”); var ReactMountReady = dereq(“./ReactMountReady”); var ReactPutListenerQueue = dereq(“./ReactPutListenerQueue”); var Transaction = dereq(“./Transaction”);
var emptyFunction = dereq(“./emptyFunction”); var mixInto = dereq(“./mixInto”);
/**
* Provides a `ReactMountReady` queue for collecting `onDOMReady` callbacks * during the performing of the transaction. */
var ON_DOM_READY_QUEUEING = {
/** * Initializes the internal `onDOMReady` queue. */ initialize: function() { this.reactMountReady.reset(); }, close: emptyFunction
};
var PUT_LISTENER_QUEUEING = {
initialize: function() { this.putListenerQueue.reset(); }, close: emptyFunction
};
/**
* Executed within the scope of the `Transaction` instance. Consider these as * being member methods, but with an implied ordering while being isolated from * each other. */
var TRANSACTION_WRAPPERS = [
PUT_LISTENER_QUEUEING, ON_DOM_READY_QUEUEING
];
/**
* @class ReactServerRenderingTransaction * @param {boolean} renderToStaticMarkup */
function ReactServerRenderingTransaction(renderToStaticMarkup) {
this.reinitializeTransaction(); this.renderToStaticMarkup = renderToStaticMarkup; this.reactMountReady = ReactMountReady.getPooled(null); this.putListenerQueue = ReactPutListenerQueue.getPooled();
}
var Mixin = {
/** * @see Transaction * @abstract * @final * @return {array} Empty list of operation wrap proceedures. */ getTransactionWrappers: function() { return TRANSACTION_WRAPPERS; }, /** * @return {object} The queue to collect `onDOMReady` callbacks with. * TODO: convert to ReactMountReady */ getReactMountReady: function() { return this.reactMountReady; }, getPutListenerQueue: function() { return this.putListenerQueue; }, /** * `PooledClass` looks for this, and will invoke this before allowing this * instance to be resused. */ destructor: function() { ReactMountReady.release(this.reactMountReady); this.reactMountReady = null; ReactPutListenerQueue.release(this.putListenerQueue); this.putListenerQueue = null; }
};
mixInto(ReactServerRenderingTransaction, Transaction.Mixin); mixInto(ReactServerRenderingTransaction, Mixin);
PooledClass.addPoolingTo(ReactServerRenderingTransaction);
module.exports = ReactServerRenderingTransaction;
},{“./PooledClass”:25,“./ReactMountReady”:61,“./ReactPutListenerQueue”:70,“./Transaction”:96,“./emptyFunction”:109,“./mixInto”:137}],75:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactStateSetters */
“use strict”;
var ReactStateSetters = {
/** * Returns a function that calls the provided function, and uses the result * of that to set the component's state. * * @param {ReactCompositeComponent} component * @param {function} funcReturningState Returned callback uses this to * determine how to update state. * @return {function} callback that when invoked uses funcReturningState to * determined the object literal to setState. */ createStateSetter: function(component, funcReturningState) { return function(a, b, c, d, e, f) { var partialState = funcReturningState.call(component, a, b, c, d, e, f); if (partialState) { component.setState(partialState); } }; }, /** * Returns a single-argument callback that can be used to update a single * key in the component's state. * * Note: this is memoized function, which makes it inexpensive to call. * * @param {ReactCompositeComponent} component * @param {string} key The key in the state that you should update. * @return {function} callback of 1 argument which calls setState() with * the provided keyName and callback argument. */ createStateKeySetter: function(component, key) { // Memoize the setters. var cache = component.__keySetters || (component.__keySetters = {}); return cache[key] || (cache[key] = createStateKeySetter(component, key)); }
};
function createStateKeySetter(component, key) {
// Partial state is allocated outside of the function closure so it can be // reused with every call, avoiding memory allocation when this function // is called. var partialState = {}; return function stateKeySetter(value) { partialState[key] = value; component.setState(partialState); };
}
ReactStateSetters.Mixin = {
/** * Returns a function that calls the provided function, and uses the result * of that to set the component's state. * * For example, these statements are equivalent: * * this.setState({x: 1}); * this.createStateSetter(function(xValue) { * return {x: xValue}; * })(1); * * @param {function} funcReturningState Returned callback uses this to * determine how to update state. * @return {function} callback that when invoked uses funcReturningState to * determined the object literal to setState. */ createStateSetter: function(funcReturningState) { return ReactStateSetters.createStateSetter(this, funcReturningState); }, /** * Returns a single-argument callback that can be used to update a single * key in the component's state. * * For example, these statements are equivalent: * * this.setState({x: 1}); * this.createStateKeySetter('x')(1); * * Note: this is memoized function, which makes it inexpensive to call. * * @param {string} key The key in the state that you should update. * @return {function} callback of 1 argument which calls setState() with * the provided keyName and callback argument. */ createStateKeySetter: function(key) { return ReactStateSetters.createStateKeySetter(this, key); }
};
module.exports = ReactStateSetters;
},{}],76:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactTestUtils */
“use strict”;
var EventConstants = dereq(“./EventConstants”); var EventPluginHub = dereq(“./EventPluginHub”); var EventPropagators = dereq(“./EventPropagators”); var React = dereq(“./React”); var ReactComponent = dereq(“./ReactComponent”); var ReactDOM = dereq(“./ReactDOM”); var ReactEventEmitter = dereq(“./ReactEventEmitter”); var ReactMount = dereq(“./ReactMount”); var ReactTextComponent = dereq(“./ReactTextComponent”); var ReactUpdates = dereq(“./ReactUpdates”); var SyntheticEvent = dereq(“./SyntheticEvent”);
var mergeInto = dereq(“./mergeInto”); var copyProperties = dereq(“./copyProperties”);
var topLevelTypes = EventConstants.topLevelTypes;
function Event(suffix) {}
/**
* @class ReactTestUtils */
/**
* Todo: Support the entire DOM.scry query syntax. For now, these simple * utilities will suffice for testing purposes. * @lends ReactTestUtils */
var ReactTestUtils = {
renderIntoDocument: function(instance) { var div = document.createElement('div'); // None of our tests actually require attaching the container to the // DOM, and doing so creates a mess that we rely on test isolation to // clean up, so we're going to stop honoring the name of this method // (and probably rename it eventually) if no problems arise. // document.documentElement.appendChild(div); return React.renderComponent(instance, div); }, isComponentOfType: function(inst, convenienceConstructor) { return ( ReactComponent.isValidComponent(inst) && inst.type === convenienceConstructor.type ); }, isDOMComponent: function(inst) { return !!(inst && ReactComponent.isValidComponent(inst) && !!inst.tagName); }, isCompositeComponent: function(inst) { if (!ReactComponent.isValidComponent(inst)) { return false; } // We check the prototype of the type that will get mounted, not the // instance itself. This is a future proof way of duck typing. var prototype = inst.type.prototype; return ( typeof prototype.render === 'function' && typeof prototype.setState === 'function' && typeof prototype.updateComponent === 'function' ); }, isCompositeComponentWithType: function(inst, type) { return !!(ReactTestUtils.isCompositeComponent(inst) && (inst.constructor === type.componentConstructor || inst.constructor === type)); }, isTextComponent: function(inst) { return inst instanceof ReactTextComponent; }, findAllInRenderedTree: function(inst, test) { if (!inst) { return []; } var ret = test(inst) ? [inst] : []; if (ReactTestUtils.isDOMComponent(inst)) { var renderedChildren = inst._renderedChildren; var key; for (key in renderedChildren) { if (!renderedChildren.hasOwnProperty(key)) { continue; } ret = ret.concat( ReactTestUtils.findAllInRenderedTree(renderedChildren[key], test) ); } } else if (ReactTestUtils.isCompositeComponent(inst)) { ret = ret.concat( ReactTestUtils.findAllInRenderedTree(inst._renderedComponent, test) ); } return ret; }, /** * Finds all instance of components in the rendered tree that are DOM * components with the class name matching `className`. * @return an array of all the matches. */ scryRenderedDOMComponentsWithClass: function(root, className) { return ReactTestUtils.findAllInRenderedTree(root, function(inst) { var instClassName = inst.props.className; return ReactTestUtils.isDOMComponent(inst) && ( instClassName && (' ' + instClassName + ' ').indexOf(' ' + className + ' ') !== -1 ); }); }, /** * Like scryRenderedDOMComponentsWithClass but expects there to be one result, * and returns that one result, or throws exception if there is any other * number of matches besides one. * @return {!ReactDOMComponent} The one match. */ findRenderedDOMComponentWithClass: function(root, className) { var all = ReactTestUtils.scryRenderedDOMComponentsWithClass(root, className); if (all.length !== 1) { throw new Error('Did not find exactly one match for class:' + className); } return all[0]; }, /** * Finds all instance of components in the rendered tree that are DOM * components with the tag name matching `tagName`. * @return an array of all the matches. */ scryRenderedDOMComponentsWithTag: function(root, tagName) { return ReactTestUtils.findAllInRenderedTree(root, function(inst) { return ReactTestUtils.isDOMComponent(inst) && inst.tagName === tagName.toUpperCase(); }); }, /** * Like scryRenderedDOMComponentsWithTag but expects there to be one result, * and returns that one result, or throws exception if there is any other * number of matches besides one. * @return {!ReactDOMComponent} The one match. */ findRenderedDOMComponentWithTag: function(root, tagName) { var all = ReactTestUtils.scryRenderedDOMComponentsWithTag(root, tagName); if (all.length !== 1) { throw new Error('Did not find exactly one match for tag:' + tagName); } return all[0]; }, /** * Finds all instances of components with type equal to `componentType`. * @return an array of all the matches. */ scryRenderedComponentsWithType: function(root, componentType) { return ReactTestUtils.findAllInRenderedTree(root, function(inst) { return ReactTestUtils.isCompositeComponentWithType(inst, componentType); }); }, /** * Same as `scryRenderedComponentsWithType` but expects there to be one result * and returns that one result, or throws exception if there is any other * number of matches besides one. * @return {!ReactComponent} The one match. */ findRenderedComponentWithType: function(root, componentType) { var all = ReactTestUtils.scryRenderedComponentsWithType( root, componentType ); if (all.length !== 1) { throw new Error( 'Did not find exactly one match for componentType:' + componentType ); } return all[0]; }, /** * Pass a mocked component module to this method to augment it with * useful methods that allow it to be used as a dummy React component. * Instead of rendering as usual, the component will become a simple * <div> containing any provided children. * * @param {object} module the mock function object exported from a * module that defines the component to be mocked * @param {?string} mockTagName optional dummy root tag name to return * from render method (overrides * module.mockTagName if provided) * @return {object} the ReactTestUtils object (for chaining) */ mockComponent: function(module, mockTagName) { var ConvenienceConstructor = React.createClass({ render: function() { var mockTagName = mockTagName || module.mockTagName || "div"; return ReactDOM[mockTagName](null, this.props.children); } }); copyProperties(module, ConvenienceConstructor); module.mockImplementation(ConvenienceConstructor); return this; }, /** * Simulates a top level event being dispatched from a raw event that occured * on an `Element` node. * @param topLevelType {Object} A type from `EventConstants.topLevelTypes` * @param {!Element} node The dom to simulate an event occurring on. * @param {?Event} fakeNativeEvent Fake native event to use in SyntheticEvent. */ simulateNativeEventOnNode: function(topLevelType, node, fakeNativeEvent) { var virtualHandler = ReactEventEmitter.TopLevelCallbackCreator.createTopLevelCallback( topLevelType ); fakeNativeEvent.target = node; virtualHandler(fakeNativeEvent); }, /** * Simulates a top level event being dispatched from a raw event that occured * on the `ReactDOMComponent` `comp`. * @param topLevelType {Object} A type from `EventConstants.topLevelTypes`. * @param comp {!ReactDOMComponent} * @param {?Event} fakeNativeEvent Fake native event to use in SyntheticEvent. */ simulateNativeEventOnDOMComponent: function( topLevelType, comp, fakeNativeEvent) { ReactTestUtils.simulateNativeEventOnNode( topLevelType, comp.getDOMNode(), fakeNativeEvent ); }, nativeTouchData: function(x, y) { return { touches: [ {pageX: x, pageY: y} ] }; }, Simulate: null, SimulateNative: {}
};
/**
* Exports: * * - `ReactTestUtils.Simulate.click(Element/ReactDOMComponent)` * - `ReactTestUtils.Simulate.mouseMove(Element/ReactDOMComponent)` * - `ReactTestUtils.Simulate.change(Element/ReactDOMComponent)` * - ... (All keys from event plugin `eventTypes` objects) */
function makeSimulator(eventType) {
return function(domComponentOrNode, eventData) { var node; if (ReactTestUtils.isDOMComponent(domComponentOrNode)) { node = domComponentOrNode.getDOMNode(); } else if (domComponentOrNode.tagName) { node = domComponentOrNode; } var fakeNativeEvent = new Event(); fakeNativeEvent.target = node; // We don't use SyntheticEvent.getPooled in order to not have to worry about // properly destroying any properties assigned from `eventData` upon release var event = new SyntheticEvent( ReactEventEmitter.eventNameDispatchConfigs[eventType], ReactMount.getID(node), fakeNativeEvent ); mergeInto(event, eventData); EventPropagators.accumulateTwoPhaseDispatches(event); ReactUpdates.batchedUpdates(function() { EventPluginHub.enqueueEvents(event); EventPluginHub.processEventQueue(); }); };
}
function buildSimulators() {
ReactTestUtils.Simulate = {}; var eventType; for (eventType in ReactEventEmitter.eventNameDispatchConfigs) { /** * @param {!Element || ReactDOMComponent} domComponentOrNode * @param {?object} eventData Fake event data to use in SyntheticEvent. */ ReactTestUtils.Simulate[eventType] = makeSimulator(eventType); }
}
// Rebuild ReactTestUtils.Simulate whenever event plugins are injected var oldInjectEventPluginOrder = EventPluginHub.injection.injectEventPluginOrder; EventPluginHub.injection.injectEventPluginOrder = function() {
oldInjectEventPluginOrder.apply(this, arguments); buildSimulators();
}; var oldInjectEventPlugins = EventPluginHub.injection.injectEventPluginsByName; EventPluginHub.injection.injectEventPluginsByName = function() {
oldInjectEventPlugins.apply(this, arguments); buildSimulators();
};
buildSimulators();
/**
* Exports: * * - `ReactTestUtils.SimulateNative.click(Element/ReactDOMComponent)` * - `ReactTestUtils.SimulateNative.mouseMove(Element/ReactDOMComponent)` * - `ReactTestUtils.SimulateNative.mouseIn/ReactDOMComponent)` * - `ReactTestUtils.SimulateNative.mouseOut(Element/ReactDOMComponent)` * - ... (All keys from `EventConstants.topLevelTypes`) * * Note: Top level event types are a subset of the entire set of handler types * (which include a broader set of "synthetic" events). For example, onDragDone * is a synthetic event. Except when testing an event plugin or React's event * handling code specifically, you probably want to use ReactTestUtils.Simulate * to dispatch synthetic events. */
function makeNativeSimulator(eventType) {
return function(domComponentOrNode, nativeEventData) { var fakeNativeEvent = new Event(eventType); mergeInto(fakeNativeEvent, nativeEventData); if (ReactTestUtils.isDOMComponent(domComponentOrNode)) { ReactTestUtils.simulateNativeEventOnDOMComponent( eventType, domComponentOrNode, fakeNativeEvent ); } else if (!!domComponentOrNode.tagName) { // Will allow on actual dom nodes. ReactTestUtils.simulateNativeEventOnNode( eventType, domComponentOrNode, fakeNativeEvent ); } };
}
var eventType; for (eventType in topLevelTypes) {
// Event type is stored as 'topClick' - we transform that to 'click' var convenienceName = eventType.indexOf('top') === 0 ? eventType.charAt(3).toLowerCase() + eventType.substr(4) : eventType; /** * @param {!Element || ReactDOMComponent} domComponentOrNode * @param {?Event} nativeEventData Fake native event to use in SyntheticEvent. */ ReactTestUtils.SimulateNative[convenienceName] = makeNativeSimulator(eventType);
}
module.exports = ReactTestUtils;
},{“./EventConstants”:15,“./EventPluginHub”:17,“./EventPropagators”:20,“./React”:26,“./ReactComponent”:31,“./ReactDOM”:36,“./ReactEventEmitter”:52,“./ReactMount”:60,“./ReactTextComponent”:77,“./ReactUpdates”:81,“./SyntheticEvent”:89,“./copyProperties”:102,“./mergeInto”:136}],77:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactTextComponent * @typechecks static-only */
“use strict”;
var DOMPropertyOperations = dereq(“./DOMPropertyOperations”); var ReactBrowserComponentMixin = dereq(“./ReactBrowserComponentMixin”); var ReactComponent = dereq(“./ReactComponent”);
var escapeTextForBrowser = dereq(“./escapeTextForBrowser”); var mixInto = dereq(“./mixInto”);
/**
* Text nodes violate a couple assumptions that React makes about components: * * - When mounting text into the DOM, adjacent text nodes are merged. * - Text nodes cannot be assigned a React root ID. * * This component is used to wrap strings in elements so that they can undergo * the same reconciliation that is applied to elements. * * TODO: Investigate representing React components in the DOM with text nodes. * * @class ReactTextComponent * @extends ReactComponent * @internal */
var ReactTextComponent = function(initialText) {
this.construct({text: initialText});
};
/**
* Used to clone the text descriptor object before it's mounted. * * @param {object} props * @return {object} A new ReactTextComponent instance */
ReactTextComponent.ConvenienceConstructor = function(props) {
return new ReactTextComponent(props.text);
};
mixInto(ReactTextComponent, ReactComponent.Mixin); mixInto(ReactTextComponent, ReactBrowserComponentMixin); mixInto(ReactTextComponent, {
/** * Creates the markup for this text node. This node is not intended to have * any features besides containing text content. * * @param {string} rootID DOM ID of the root node. * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction * @param {number} mountDepth number of components in the owner hierarchy * @return {string} Markup for this text node. * @internal */ mountComponent: function(rootID, transaction, mountDepth) { ReactComponent.Mixin.mountComponent.call( this, rootID, transaction, mountDepth ); var escapedText = escapeTextForBrowser(this.props.text); if (transaction.renderToStaticMarkup) { // Normally we'd wrap this in a `span` for the reasons stated above, but // since this is a situation where React won't take over (static pages), // we can simply return the text as it is. return escapedText; } return ( '<span ' + DOMPropertyOperations.createMarkupForID(rootID) + '>' + escapedText + '</span>' ); }, /** * Updates this component by updating the text content. * * @param {object} nextComponent Contains the next text content. * @param {ReactReconcileTransaction} transaction * @internal */ receiveComponent: function(nextComponent, transaction) { var nextProps = nextComponent.props; if (nextProps.text !== this.props.text) { this.props.text = nextProps.text; ReactComponent.BackendIDOperations.updateTextContentByID( this._rootNodeID, nextProps.text ); } }
});
// Expose the constructor on itself and the prototype for consistency with other // descriptors. ReactTextComponent.type = ReactTextComponent; ReactTextComponent.prototype.type = ReactTextComponent;
module.exports = ReactTextComponent;
},{“./DOMPropertyOperations”:10,“./ReactBrowserComponentMixin”:27,“./ReactComponent”:31,“./escapeTextForBrowser”:111,“./mixInto”:137}],78:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @typechecks static-only * @providesModule ReactTransitionChildMapping */
“use strict”;
var ReactChildren = dereq(“./ReactChildren”);
var ReactTransitionChildMapping = {
/** * Given `this.props.children`, return an object mapping key to child. Just * simple syntactic sugar around ReactChildren.map(). * * @param {*} children `this.props.children` * @return {object} Mapping of key to child */ getChildMapping: function(children) { return ReactChildren.map(children, function(child) { return child; }); }, /** * When you're adding or removing children some may be added or removed in the * same render pass. We want ot show *both* since we want to simultaneously * animate elements in and out. This function takes a previous set of keys * and a new set of keys and merges them with its best guess of the correct * ordering. In the future we may expose some of the utilities in * ReactMultiChild to make this easy, but for now React itself does not * directly have this concept of the union of prevChildren and nextChildren * so we implement it here. * * @param {object} prev prev children as returned from * `ReactTransitionChildMapping.getChildMapping()`. * @param {object} next next children as returned from * `ReactTransitionChildMapping.getChildMapping()`. * @return {object} a key set that contains all keys in `prev` and all keys * in `next` in a reasonable order. */ mergeChildMappings: function(prev, next) { prev = prev || {}; next = next || {}; function getValueForKey(key) { if (next.hasOwnProperty(key)) { return next[key]; } else { return prev[key]; } } // For each key of `next`, the list of keys to insert before that key in // the combined list var nextKeysPending = {}; var pendingKeys = []; for (var prevKey in prev) { if (next[prevKey]) { if (pendingKeys.length) { nextKeysPending[prevKey] = pendingKeys; pendingKeys = []; } } else { pendingKeys.push(prevKey); } } var i; var childMapping = {}; for (var nextKey in next) { if (nextKeysPending[nextKey]) { for (i = 0; i < nextKeysPending[nextKey].length; i++) { var pendingNextKey = nextKeysPending[nextKey][i]; childMapping[nextKeysPending[nextKey][i]] = getValueForKey( pendingNextKey ); } } childMapping[nextKey] = getValueForKey(nextKey); } // Finally, add the keys which didn't appear before any key in `next` for (i = 0; i < pendingKeys.length; i++) { childMapping[pendingKeys[i]] = getValueForKey(pendingKeys[i]); } return childMapping; }
};
module.exports = ReactTransitionChildMapping;
},{“./ReactChildren”:30}],79:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactTransitionEvents */
“use strict”;
var ExecutionEnvironment = dereq(“./ExecutionEnvironment”);
var EVENT_NAME_MAP = {
transitionend: { 'transition': 'transitionend', 'WebkitTransition': 'webkitTransitionEnd', 'MozTransition': 'mozTransitionEnd', 'OTransition': 'oTransitionEnd', 'msTransition': 'MSTransitionEnd' }, animationend: { 'animation': 'animationend', 'WebkitAnimation': 'webkitAnimationEnd', 'MozAnimation': 'mozAnimationEnd', 'OAnimation': 'oAnimationEnd', 'msAnimation': 'MSAnimationEnd' }
};
var endEvents = [];
function detectEvents() {
var testEl = document.createElement('div'); var style = testEl.style; for (var baseEventName in EVENT_NAME_MAP) { var baseEvents = EVENT_NAME_MAP[baseEventName]; for (var styleName in baseEvents) { if (styleName in style) { endEvents.push(baseEvents[styleName]); break; } } }
}
if (ExecutionEnvironment.canUseDOM) {
detectEvents();
}
// We use the raw {add|remove}EventListener() call because EventListener // does not know how to remove event listeners and we really should // clean up. Also, these events are not triggered in older browsers // so we should be A-OK here.
function addEventListener(node, eventName, eventListener) {
node.addEventListener(eventName, eventListener, false);
}
function removeEventListener(node, eventName, eventListener) {
node.removeEventListener(eventName, eventListener, false);
}
var ReactTransitionEvents = {
addEndEventListener: function(node, eventListener) { if (endEvents.length === 0) { // If CSS transitions are not supported, trigger an "end animation" // event immediately. window.setTimeout(eventListener, 0); return; } endEvents.forEach(function(endEvent) { addEventListener(node, endEvent, eventListener); }); }, removeEndEventListener: function(node, eventListener) { if (endEvents.length === 0) { return; } endEvents.forEach(function(endEvent) { removeEventListener(node, endEvent, eventListener); }); }
};
module.exports = ReactTransitionEvents;
},{“./ExecutionEnvironment”:21}],80:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactTransitionGroup */
“use strict”;
var React = dereq(“./React”); var ReactTransitionChildMapping = dereq(“./ReactTransitionChildMapping”);
var cloneWithProps = dereq(“./cloneWithProps”); var emptyFunction = dereq(“./emptyFunction”); var merge = dereq(“./merge”);
var ReactTransitionGroup = React.createClass({
propTypes: { component: React.PropTypes.func, childFactory: React.PropTypes.func }, getDefaultProps: function() { return { component: React.DOM.span, childFactory: emptyFunction.thatReturnsArgument }; }, getInitialState: function() { return { children: ReactTransitionChildMapping.getChildMapping(this.props.children) }; }, componentWillReceiveProps: function(nextProps) { var nextChildMapping = ReactTransitionChildMapping.getChildMapping( nextProps.children ); var prevChildMapping = this.state.children; this.setState({ children: ReactTransitionChildMapping.mergeChildMappings( prevChildMapping, nextChildMapping ) }); var key; for (key in nextChildMapping) { if (!prevChildMapping.hasOwnProperty(key) && !this.currentlyTransitioningKeys[key]) { this.keysToEnter.push(key); } } for (key in prevChildMapping) { if (!nextChildMapping.hasOwnProperty(key) && !this.currentlyTransitioningKeys[key]) { this.keysToLeave.push(key); } } // If we want to someday check for reordering, we could do it here. }, componentWillMount: function() { this.currentlyTransitioningKeys = {}; this.keysToEnter = []; this.keysToLeave = []; }, componentDidUpdate: function() { var keysToEnter = this.keysToEnter; this.keysToEnter = []; keysToEnter.forEach(this.performEnter); var keysToLeave = this.keysToLeave; this.keysToLeave = []; keysToLeave.forEach(this.performLeave); }, performEnter: function(key) { this.currentlyTransitioningKeys[key] = true; var component = this.refs[key]; if (component.componentWillEnter) { component.componentWillEnter( this._handleDoneEntering.bind(this, key) ); } else { this._handleDoneEntering(key); } }, _handleDoneEntering: function(key) { var component = this.refs[key]; if (component.componentDidEnter) { component.componentDidEnter(); } delete this.currentlyTransitioningKeys[key]; var currentChildMapping = ReactTransitionChildMapping.getChildMapping( this.props.children ); if (!currentChildMapping.hasOwnProperty(key)) { // This was removed before it had fully entered. Remove it. this.performLeave(key); } }, performLeave: function(key) { this.currentlyTransitioningKeys[key] = true; var component = this.refs[key]; if (component.componentWillLeave) { component.componentWillLeave(this._handleDoneLeaving.bind(this, key)); } else { // Note that this is somewhat dangerous b/c it calls setState() // again, effectively mutating the component before all the work // is done. this._handleDoneLeaving(key); } }, _handleDoneLeaving: function(key) { var component = this.refs[key]; if (component.componentDidLeave) { component.componentDidLeave(); } delete this.currentlyTransitioningKeys[key]; var currentChildMapping = ReactTransitionChildMapping.getChildMapping( this.props.children ); if (currentChildMapping.hasOwnProperty(key)) { // This entered again before it fully left. Add it again. this.performEnter(key); } else { var newChildren = merge(this.state.children); delete newChildren[key]; this.setState({children: newChildren}); } }, render: function() { // TODO: we could get rid of the need for the wrapper node // by cloning a single child var childrenToRender = {}; for (var key in this.state.children) { var child = this.state.children[key]; if (child) { // You may need to apply reactive updates to a child as it is leaving. // The normal React way to do it won't work since the child will have // already been removed. In case you need this behavior you can provide // a childFactory function to wrap every child, even the ones that are // leaving. childrenToRender[key] = cloneWithProps( this.props.childFactory(child), {ref: key} ); } } return this.transferPropsTo(this.props.component(null, childrenToRender)); }
});
module.exports = ReactTransitionGroup;
},{“./React”:26,“./ReactTransitionChildMapping”:78,“./cloneWithProps”:100,“./emptyFunction”:109,“./merge”:134}],81:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactUpdates */
“use strict”;
var ReactPerf = dereq(“./ReactPerf”);
var invariant = dereq(“./invariant”);
var dirtyComponents = [];
var batchingStrategy = null;
function ensureBatchingStrategy() {
("production" !== "development" ? invariant(batchingStrategy, 'ReactUpdates: must inject a batching strategy') : invariant(batchingStrategy));
}
function batchedUpdates(callback, param) {
ensureBatchingStrategy(); batchingStrategy.batchedUpdates(callback, param);
}
/**
* Array comparator for ReactComponents by owner depth * * @param {ReactComponent} c1 first component you're comparing * @param {ReactComponent} c2 second component you're comparing * @return {number} Return value usable by Array.prototype.sort(). */
function mountDepthComparator(c1, c2) {
return c1._mountDepth - c2._mountDepth;
}
function runBatchedUpdates() {
// Since reconciling a component higher in the owner hierarchy usually (not // always -- see shouldComponentUpdate()) will reconcile children, reconcile // them before their children by sorting the array. dirtyComponents.sort(mountDepthComparator); for (var i = 0; i < dirtyComponents.length; i++) { // If a component is unmounted before pending changes apply, ignore them // TODO: Queue unmounts in the same list to avoid this happening at all var component = dirtyComponents[i]; if (component.isMounted()) { // If performUpdateIfNecessary happens to enqueue any new updates, we // shouldn't execute the callbacks until the next render happens, so // stash the callbacks first var callbacks = component._pendingCallbacks; component._pendingCallbacks = null; component.performUpdateIfNecessary(); if (callbacks) { for (var j = 0; j < callbacks.length; j++) { callbacks[j].call(component); } } } }
}
function clearDirtyComponents() {
dirtyComponents.length = 0;
}
var flushBatchedUpdates = ReactPerf.measure(
'ReactUpdates', 'flushBatchedUpdates', function() { // Run these in separate functions so the JIT can optimize try { runBatchedUpdates(); } finally { clearDirtyComponents(); } }
);
/**
* Mark a component as needing a rerender, adding an optional callback to a * list of functions which will be executed once the rerender occurs. */
function enqueueUpdate(component, callback) {
("production" !== "development" ? invariant( !callback || typeof callback === "function", 'enqueueUpdate(...): You called `setProps`, `replaceProps`, ' + '`setState`, `replaceState`, or `forceUpdate` with a callback that ' + 'isn\'t callable.' ) : invariant(!callback || typeof callback === "function")); ensureBatchingStrategy(); if (!batchingStrategy.isBatchingUpdates) { component.performUpdateIfNecessary(); callback && callback.call(component); return; } dirtyComponents.push(component); if (callback) { if (component._pendingCallbacks) { component._pendingCallbacks.push(callback); } else { component._pendingCallbacks = [callback]; } }
}
var ReactUpdatesInjection = {
injectBatchingStrategy: function(_batchingStrategy) { ("production" !== "development" ? invariant( _batchingStrategy, 'ReactUpdates: must provide a batching strategy' ) : invariant(_batchingStrategy)); ("production" !== "development" ? invariant( typeof _batchingStrategy.batchedUpdates === 'function', 'ReactUpdates: must provide a batchedUpdates() function' ) : invariant(typeof _batchingStrategy.batchedUpdates === 'function')); ("production" !== "development" ? invariant( typeof _batchingStrategy.isBatchingUpdates === 'boolean', 'ReactUpdates: must provide an isBatchingUpdates boolean attribute' ) : invariant(typeof _batchingStrategy.isBatchingUpdates === 'boolean')); batchingStrategy = _batchingStrategy; }
};
var ReactUpdates = {
batchedUpdates: batchedUpdates, enqueueUpdate: enqueueUpdate, flushBatchedUpdates: flushBatchedUpdates, injection: ReactUpdatesInjection
};
module.exports = ReactUpdates;
},{“./ReactPerf”:65,“./invariant”:125}],82:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ReactWithAddons */
/**
* This module exists purely in the open source project, and is meant as a way * to create a separate standalone build of React. This build has "addons", or * functionality we've built and think might be useful but doesn't have a good * place to live inside React core. */
“use strict”;
var LinkedStateMixin = dereq(“./LinkedStateMixin”); var React = dereq(“./React”); var ReactCSSTransitionGroup = dereq(“./ReactCSSTransitionGroup”); var ReactTransitionGroup = dereq(“./ReactTransitionGroup”); var ReactCSSTransitionGroup = dereq(“./ReactCSSTransitionGroup”);
var cx = dereq(“./cx”); var cloneWithProps = dereq(“./cloneWithProps”); var update = dereq(“./update”);
React.addons = {
LinkedStateMixin: LinkedStateMixin, CSSTransitionGroup: ReactCSSTransitionGroup, TransitionGroup: ReactTransitionGroup, classSet: cx, cloneWithProps: cloneWithProps, update: update
};
if (“production” !== “development”) {
React.addons.TestUtils = _dereq_("./ReactTestUtils");
}
module.exports = React;
},{“./LinkedStateMixin”:22,“./React”:26,“./ReactCSSTransitionGroup”:28,“./ReactTestUtils”:76,“./ReactTransitionGroup”:80,“./cloneWithProps”:100,“./cx”:107,“./update”:147}],83:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule SelectEventPlugin */
“use strict”;
var EventConstants = dereq(“./EventConstants”); var EventPropagators = dereq(“./EventPropagators”); var ReactInputSelection = dereq(“./ReactInputSelection”); var SyntheticEvent = dereq(“./SyntheticEvent”);
var getActiveElement = dereq(“./getActiveElement”); var isTextInputElement = dereq(“./isTextInputElement”); var keyOf = dereq(“./keyOf”); var shallowEqual = dereq(“./shallowEqual”);
var topLevelTypes = EventConstants.topLevelTypes;
var eventTypes = {
select: { phasedRegistrationNames: { bubbled: keyOf({onSelect: null}), captured: keyOf({onSelectCapture: null}) }, dependencies: [ topLevelTypes.topBlur, topLevelTypes.topContextMenu, topLevelTypes.topFocus, topLevelTypes.topKeyDown, topLevelTypes.topMouseDown, topLevelTypes.topMouseUp, topLevelTypes.topSelectionChange ] }
};
var activeElement = null; var activeElementID = null; var lastSelection = null; var mouseDown = false;
/**
* Get an object which is a unique representation of the current selection. * * The return value will not be consistent across nodes or browsers, but * two identical selections on the same node will return identical objects. * * @param {DOMElement} node * @param {object} */
function getSelection(node) {
if ('selectionStart' in node && ReactInputSelection.hasSelectionCapabilities(node)) { return { start: node.selectionStart, end: node.selectionEnd }; } else if (document.selection) { var range = document.selection.createRange(); return { parentElement: range.parentElement(), text: range.text, top: range.boundingTop, left: range.boundingLeft }; } else { var selection = window.getSelection(); return { anchorNode: selection.anchorNode, anchorOffset: selection.anchorOffset, focusNode: selection.focusNode, focusOffset: selection.focusOffset }; }
}
/**
* Poll selection to see whether it's changed. * * @param {object} nativeEvent * @return {?SyntheticEvent} */
function constructSelectEvent(nativeEvent) {
// Ensure we have the right element, and that the user is not dragging a // selection (this matches native `select` event behavior). In HTML5, select // fires only on input and textarea thus if there's no focused element we // won't dispatch. if (mouseDown || activeElement == null || activeElement != getActiveElement()) { return; } // Only fire when selection has actually changed. var currentSelection = getSelection(activeElement); if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) { lastSelection = currentSelection; var syntheticEvent = SyntheticEvent.getPooled( eventTypes.select, activeElementID, nativeEvent ); syntheticEvent.type = 'select'; syntheticEvent.target = activeElement; EventPropagators.accumulateTwoPhaseDispatches(syntheticEvent); return syntheticEvent; }
}
/**
* This plugin creates an `onSelect` event that normalizes select events * across form elements. * * Supported elements are: * - input (see `isTextInputElement`) * - textarea * - contentEditable * * This differs from native browser implementations in the following ways: * - Fires on contentEditable fields as well as inputs. * - Fires for collapsed selection. * - Fires after user input. */
var SelectEventPlugin = {
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) { switch (topLevelType) { // Track the input node that has focus. case topLevelTypes.topFocus: if (isTextInputElement(topLevelTarget) || topLevelTarget.contentEditable === 'true') { activeElement = topLevelTarget; activeElementID = topLevelTargetID; lastSelection = null; } break; case topLevelTypes.topBlur: activeElement = null; activeElementID = null; lastSelection = null; break; // Don't fire the event while the user is dragging. This matches the // semantics of the native select event. case topLevelTypes.topMouseDown: mouseDown = true; break; case topLevelTypes.topContextMenu: case topLevelTypes.topMouseUp: mouseDown = false; return constructSelectEvent(nativeEvent); // Chrome and IE fire non-standard event when selection is changed (and // sometimes when it hasn't). // Firefox doesn't support selectionchange, so check selection status // after each key entry. The selection changes after keydown and before // keyup, but we check on keydown as well in the case of holding down a // key, when multiple keydown events are fired but only one keyup is. case topLevelTypes.topSelectionChange: case topLevelTypes.topKeyDown: case topLevelTypes.topKeyUp: return constructSelectEvent(nativeEvent); } }
};
module.exports = SelectEventPlugin;
},{“./EventConstants”:15,“./EventPropagators”:20,“./ReactInputSelection”:56,“./SyntheticEvent”:89,“./getActiveElement”:115,“./isTextInputElement”:128,“./keyOf”:132,“./shallowEqual”:143}],84:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ServerReactRootIndex * @typechecks */
“use strict”;
/**
* Size of the reactRoot ID space. We generate random numbers for React root * IDs and if there's a collision the events and DOM update system will * get confused. In the future we need a way to generate GUIDs but for * now this will work on a smaller scale. */
var GLOBAL_MOUNT_POINT_MAX = Math.pow(2, 53);
var ServerReactRootIndex = {
createReactRootIndex: function() { return Math.ceil(Math.random() * GLOBAL_MOUNT_POINT_MAX); }
};
module.exports = ServerReactRootIndex;
},{}],85:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule SimpleEventPlugin */
“use strict”;
var EventConstants = dereq(“./EventConstants”); var EventPluginUtils = dereq(“./EventPluginUtils”); var EventPropagators = dereq(“./EventPropagators”); var SyntheticClipboardEvent = dereq(“./SyntheticClipboardEvent”); var SyntheticEvent = dereq(“./SyntheticEvent”); var SyntheticFocusEvent = dereq(“./SyntheticFocusEvent”); var SyntheticKeyboardEvent = dereq(“./SyntheticKeyboardEvent”); var SyntheticMouseEvent = dereq(“./SyntheticMouseEvent”); var SyntheticDragEvent = dereq(“./SyntheticDragEvent”); var SyntheticTouchEvent = dereq(“./SyntheticTouchEvent”); var SyntheticUIEvent = dereq(“./SyntheticUIEvent”); var SyntheticWheelEvent = dereq(“./SyntheticWheelEvent”);
var invariant = dereq(“./invariant”); var keyOf = dereq(“./keyOf”);
var topLevelTypes = EventConstants.topLevelTypes;
var eventTypes = {
blur: { phasedRegistrationNames: { bubbled: keyOf({onBlur: true}), captured: keyOf({onBlurCapture: true}) } }, click: { phasedRegistrationNames: { bubbled: keyOf({onClick: true}), captured: keyOf({onClickCapture: true}) } }, contextMenu: { phasedRegistrationNames: { bubbled: keyOf({onContextMenu: true}), captured: keyOf({onContextMenuCapture: true}) } }, copy: { phasedRegistrationNames: { bubbled: keyOf({onCopy: true}), captured: keyOf({onCopyCapture: true}) } }, cut: { phasedRegistrationNames: { bubbled: keyOf({onCut: true}), captured: keyOf({onCutCapture: true}) } }, doubleClick: { phasedRegistrationNames: { bubbled: keyOf({onDoubleClick: true}), captured: keyOf({onDoubleClickCapture: true}) } }, drag: { phasedRegistrationNames: { bubbled: keyOf({onDrag: true}), captured: keyOf({onDragCapture: true}) } }, dragEnd: { phasedRegistrationNames: { bubbled: keyOf({onDragEnd: true}), captured: keyOf({onDragEndCapture: true}) } }, dragEnter: { phasedRegistrationNames: { bubbled: keyOf({onDragEnter: true}), captured: keyOf({onDragEnterCapture: true}) } }, dragExit: { phasedRegistrationNames: { bubbled: keyOf({onDragExit: true}), captured: keyOf({onDragExitCapture: true}) } }, dragLeave: { phasedRegistrationNames: { bubbled: keyOf({onDragLeave: true}), captured: keyOf({onDragLeaveCapture: true}) } }, dragOver: { phasedRegistrationNames: { bubbled: keyOf({onDragOver: true}), captured: keyOf({onDragOverCapture: true}) } }, dragStart: { phasedRegistrationNames: { bubbled: keyOf({onDragStart: true}), captured: keyOf({onDragStartCapture: true}) } }, drop: { phasedRegistrationNames: { bubbled: keyOf({onDrop: true}), captured: keyOf({onDropCapture: true}) } }, focus: { phasedRegistrationNames: { bubbled: keyOf({onFocus: true}), captured: keyOf({onFocusCapture: true}) } }, input: { phasedRegistrationNames: { bubbled: keyOf({onInput: true}), captured: keyOf({onInputCapture: true}) } }, keyDown: { phasedRegistrationNames: { bubbled: keyOf({onKeyDown: true}), captured: keyOf({onKeyDownCapture: true}) } }, keyPress: { phasedRegistrationNames: { bubbled: keyOf({onKeyPress: true}), captured: keyOf({onKeyPressCapture: true}) } }, keyUp: { phasedRegistrationNames: { bubbled: keyOf({onKeyUp: true}), captured: keyOf({onKeyUpCapture: true}) } }, load: { phasedRegistrationNames: { bubbled: keyOf({onLoad: true}), captured: keyOf({onLoadCapture: true}) } }, error: { phasedRegistrationNames: { bubbled: keyOf({onError: true}), captured: keyOf({onErrorCapture: true}) } }, // Note: We do not allow listening to mouseOver events. Instead, use the // onMouseEnter/onMouseLeave created by `EnterLeaveEventPlugin`. mouseDown: { phasedRegistrationNames: { bubbled: keyOf({onMouseDown: true}), captured: keyOf({onMouseDownCapture: true}) } }, mouseMove: { phasedRegistrationNames: { bubbled: keyOf({onMouseMove: true}), captured: keyOf({onMouseMoveCapture: true}) } }, mouseOut: { phasedRegistrationNames: { bubbled: keyOf({onMouseOut: true}), captured: keyOf({onMouseOutCapture: true}) } }, mouseOver: { phasedRegistrationNames: { bubbled: keyOf({onMouseOver: true}), captured: keyOf({onMouseOverCapture: true}) } }, mouseUp: { phasedRegistrationNames: { bubbled: keyOf({onMouseUp: true}), captured: keyOf({onMouseUpCapture: true}) } }, paste: { phasedRegistrationNames: { bubbled: keyOf({onPaste: true}), captured: keyOf({onPasteCapture: true}) } }, reset: { phasedRegistrationNames: { bubbled: keyOf({onReset: true}), captured: keyOf({onResetCapture: true}) } }, scroll: { phasedRegistrationNames: { bubbled: keyOf({onScroll: true}), captured: keyOf({onScrollCapture: true}) } }, submit: { phasedRegistrationNames: { bubbled: keyOf({onSubmit: true}), captured: keyOf({onSubmitCapture: true}) } }, touchCancel: { phasedRegistrationNames: { bubbled: keyOf({onTouchCancel: true}), captured: keyOf({onTouchCancelCapture: true}) } }, touchEnd: { phasedRegistrationNames: { bubbled: keyOf({onTouchEnd: true}), captured: keyOf({onTouchEndCapture: true}) } }, touchMove: { phasedRegistrationNames: { bubbled: keyOf({onTouchMove: true}), captured: keyOf({onTouchMoveCapture: true}) } }, touchStart: { phasedRegistrationNames: { bubbled: keyOf({onTouchStart: true}), captured: keyOf({onTouchStartCapture: true}) } }, wheel: { phasedRegistrationNames: { bubbled: keyOf({onWheel: true}), captured: keyOf({onWheelCapture: true}) } }
};
var topLevelEventsToDispatchConfig = {
topBlur: eventTypes.blur, topClick: eventTypes.click, topContextMenu: eventTypes.contextMenu, topCopy: eventTypes.copy, topCut: eventTypes.cut, topDoubleClick: eventTypes.doubleClick, topDrag: eventTypes.drag, topDragEnd: eventTypes.dragEnd, topDragEnter: eventTypes.dragEnter, topDragExit: eventTypes.dragExit, topDragLeave: eventTypes.dragLeave, topDragOver: eventTypes.dragOver, topDragStart: eventTypes.dragStart, topDrop: eventTypes.drop, topError: eventTypes.error, topFocus: eventTypes.focus, topInput: eventTypes.input, topKeyDown: eventTypes.keyDown, topKeyPress: eventTypes.keyPress, topKeyUp: eventTypes.keyUp, topLoad: eventTypes.load, topMouseDown: eventTypes.mouseDown, topMouseMove: eventTypes.mouseMove, topMouseOut: eventTypes.mouseOut, topMouseOver: eventTypes.mouseOver, topMouseUp: eventTypes.mouseUp, topPaste: eventTypes.paste, topReset: eventTypes.reset, topScroll: eventTypes.scroll, topSubmit: eventTypes.submit, topTouchCancel: eventTypes.touchCancel, topTouchEnd: eventTypes.touchEnd, topTouchMove: eventTypes.touchMove, topTouchStart: eventTypes.touchStart, topWheel: eventTypes.wheel
};
for (var topLevelType in topLevelEventsToDispatchConfig) {
topLevelEventsToDispatchConfig[topLevelType].dependencies = [topLevelType];
}
var SimpleEventPlugin = {
eventTypes: eventTypes, /** * Same as the default implementation, except cancels the event when return * value is false. * * @param {object} Event to be dispatched. * @param {function} Application-level callback. * @param {string} domID DOM ID to pass to the callback. */ executeDispatch: function(event, listener, domID) { var returnValue = EventPluginUtils.executeDispatch(event, listener, domID); if (returnValue === false) { event.stopPropagation(); event.preventDefault(); } }, /** * @param {string} topLevelType Record from `EventConstants`. * @param {DOMEventTarget} topLevelTarget The listening component root node. * @param {string} topLevelTargetID ID of `topLevelTarget`. * @param {object} nativeEvent Native browser event. * @return {*} An accumulation of synthetic events. * @see {EventPluginHub.extractEvents} */ extractEvents: function( topLevelType, topLevelTarget, topLevelTargetID, nativeEvent) { var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType]; if (!dispatchConfig) { return null; } var EventConstructor; switch (topLevelType) { case topLevelTypes.topInput: case topLevelTypes.topLoad: case topLevelTypes.topError: case topLevelTypes.topReset: case topLevelTypes.topSubmit: // HTML Events // @see http://www.w3.org/TR/html5/index.html#events-0 EventConstructor = SyntheticEvent; break; case topLevelTypes.topKeyDown: case topLevelTypes.topKeyPress: case topLevelTypes.topKeyUp: EventConstructor = SyntheticKeyboardEvent; break; case topLevelTypes.topBlur: case topLevelTypes.topFocus: EventConstructor = SyntheticFocusEvent; break; case topLevelTypes.topClick: // Firefox creates a click event on right mouse clicks. This removes the // unwanted click events. if (nativeEvent.button === 2) { return null; } /* falls through */ case topLevelTypes.topContextMenu: case topLevelTypes.topDoubleClick: case topLevelTypes.topMouseDown: case topLevelTypes.topMouseMove: case topLevelTypes.topMouseOut: case topLevelTypes.topMouseOver: case topLevelTypes.topMouseUp: EventConstructor = SyntheticMouseEvent; break; case topLevelTypes.topDrag: case topLevelTypes.topDragEnd: case topLevelTypes.topDragEnter: case topLevelTypes.topDragExit: case topLevelTypes.topDragLeave: case topLevelTypes.topDragOver: case topLevelTypes.topDragStart: case topLevelTypes.topDrop: EventConstructor = SyntheticDragEvent; break; case topLevelTypes.topTouchCancel: case topLevelTypes.topTouchEnd: case topLevelTypes.topTouchMove: case topLevelTypes.topTouchStart: EventConstructor = SyntheticTouchEvent; break; case topLevelTypes.topScroll: EventConstructor = SyntheticUIEvent; break; case topLevelTypes.topWheel: EventConstructor = SyntheticWheelEvent; break; case topLevelTypes.topCopy: case topLevelTypes.topCut: case topLevelTypes.topPaste: EventConstructor = SyntheticClipboardEvent; break; } ("production" !== "development" ? invariant( EventConstructor, 'SimpleEventPlugin: Unhandled event type, `%s`.', topLevelType ) : invariant(EventConstructor)); var event = EventConstructor.getPooled( dispatchConfig, topLevelTargetID, nativeEvent ); EventPropagators.accumulateTwoPhaseDispatches(event); return event; }
};
module.exports = SimpleEventPlugin;
},{“./EventConstants”:15,“./EventPluginUtils”:19,“./EventPropagators”:20,“./SyntheticClipboardEvent”:86,“./SyntheticDragEvent”:88,“./SyntheticEvent”:89,“./SyntheticFocusEvent”:90,“./SyntheticKeyboardEvent”:91,“./SyntheticMouseEvent”:92,“./SyntheticTouchEvent”:93,“./SyntheticUIEvent”:94,“./SyntheticWheelEvent”:95,“./invariant”:125,“./keyOf”:132}],86:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule SyntheticClipboardEvent * @typechecks static-only */
“use strict”;
var SyntheticEvent = dereq(“./SyntheticEvent”);
/**
* @interface Event * @see http://www.w3.org/TR/clipboard-apis/ */
var ClipboardEventInterface = {
clipboardData: function(event) { return ( 'clipboardData' in event ? event.clipboardData : window.clipboardData ); }
};
/**
* @param {object} dispatchConfig Configuration used to dispatch this event. * @param {string} dispatchMarker Marker identifying the event target. * @param {object} nativeEvent Native browser event. * @extends {SyntheticUIEvent} */
function SyntheticClipboardEvent(dispatchConfig, dispatchMarker, nativeEvent) {
SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
}
SyntheticEvent.augmentClass(SyntheticClipboardEvent, ClipboardEventInterface);
module.exports = SyntheticClipboardEvent;
},{“./SyntheticEvent”:89}],87:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule SyntheticCompositionEvent * @typechecks static-only */
“use strict”;
var SyntheticEvent = dereq(“./SyntheticEvent”);
/**
* @interface Event * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents */
var CompositionEventInterface = {
data: null
};
/**
* @param {object} dispatchConfig Configuration used to dispatch this event. * @param {string} dispatchMarker Marker identifying the event target. * @param {object} nativeEvent Native browser event. * @extends {SyntheticUIEvent} */
function SyntheticCompositionEvent(
dispatchConfig, dispatchMarker, nativeEvent) { SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
}
SyntheticEvent.augmentClass(
SyntheticCompositionEvent, CompositionEventInterface
);
module.exports = SyntheticCompositionEvent;
},{“./SyntheticEvent”:89}],88:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule SyntheticDragEvent * @typechecks static-only */
“use strict”;
var SyntheticMouseEvent = dereq(“./SyntheticMouseEvent”);
/**
* @interface DragEvent * @see http://www.w3.org/TR/DOM-Level-3-Events/ */
var DragEventInterface = {
dataTransfer: null
};
/**
* @param {object} dispatchConfig Configuration used to dispatch this event. * @param {string} dispatchMarker Marker identifying the event target. * @param {object} nativeEvent Native browser event. * @extends {SyntheticUIEvent} */
function SyntheticDragEvent(dispatchConfig, dispatchMarker, nativeEvent) {
SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
}
SyntheticMouseEvent.augmentClass(SyntheticDragEvent, DragEventInterface);
module.exports = SyntheticDragEvent;
},{“./SyntheticMouseEvent”:92}],89:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule SyntheticEvent * @typechecks static-only */
“use strict”;
var PooledClass = dereq(“./PooledClass”);
var emptyFunction = dereq(“./emptyFunction”); var getEventTarget = dereq(“./getEventTarget”); var merge = dereq(“./merge”); var mergeInto = dereq(“./mergeInto”);
/**
* @interface Event * @see http://www.w3.org/TR/DOM-Level-3-Events/ */
var EventInterface = {
type: null, target: getEventTarget, // currentTarget is set when dispatching; no use in copying it here currentTarget: emptyFunction.thatReturnsNull, eventPhase: null, bubbles: null, cancelable: null, timeStamp: function(event) { return event.timeStamp || Date.now(); }, defaultPrevented: null, isTrusted: null
};
/**
* Synthetic events are dispatched by event plugins, typically in response to a * top-level event delegation handler. * * These systems should generally use pooling to reduce the frequency of garbage * collection. The system should check `isPersistent` to determine whether the * event should be released into the pool after being dispatched. Users that * need a persisted event should invoke `persist`. * * Synthetic events (and subclasses) implement the DOM Level 3 Events API by * normalizing browser quirks. Subclasses do not necessarily have to implement a * DOM interface; custom application-specific events can also subclass this. * * @param {object} dispatchConfig Configuration used to dispatch this event. * @param {string} dispatchMarker Marker identifying the event target. * @param {object} nativeEvent Native browser event. */
function SyntheticEvent(dispatchConfig, dispatchMarker, nativeEvent) {
this.dispatchConfig = dispatchConfig; this.dispatchMarker = dispatchMarker; this.nativeEvent = nativeEvent; var Interface = this.constructor.Interface; for (var propName in Interface) { if (!Interface.hasOwnProperty(propName)) { continue; } var normalize = Interface[propName]; if (normalize) { this[propName] = normalize(nativeEvent); } else { this[propName] = nativeEvent[propName]; } } var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false; if (defaultPrevented) { this.isDefaultPrevented = emptyFunction.thatReturnsTrue; } else { this.isDefaultPrevented = emptyFunction.thatReturnsFalse; } this.isPropagationStopped = emptyFunction.thatReturnsFalse;
}
mergeInto(SyntheticEvent.prototype, {
preventDefault: function() { this.defaultPrevented = true; var event = this.nativeEvent; event.preventDefault ? event.preventDefault() : event.returnValue = false; this.isDefaultPrevented = emptyFunction.thatReturnsTrue; }, stopPropagation: function() { var event = this.nativeEvent; event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true; this.isPropagationStopped = emptyFunction.thatReturnsTrue; }, /** * We release all dispatched `SyntheticEvent`s after each event loop, adding * them back into the pool. This allows a way to hold onto a reference that * won't be added back into the pool. */ persist: function() { this.isPersistent = emptyFunction.thatReturnsTrue; }, /** * Checks if this event should be released back into the pool. * * @return {boolean} True if this should not be released, false otherwise. */ isPersistent: emptyFunction.thatReturnsFalse, /** * `PooledClass` looks for `destructor` on each instance it releases. */ destructor: function() { var Interface = this.constructor.Interface; for (var propName in Interface) { this[propName] = null; } this.dispatchConfig = null; this.dispatchMarker = null; this.nativeEvent = null; }
});
SyntheticEvent.Interface = EventInterface;
/**
* Helper to reduce boilerplate when creating subclasses. * * @param {function} Class * @param {?object} Interface */
SyntheticEvent.augmentClass = function(Class, Interface) {
var Super = this; var prototype = Object.create(Super.prototype); mergeInto(prototype, Class.prototype); Class.prototype = prototype; Class.prototype.constructor = Class; Class.Interface = merge(Super.Interface, Interface); Class.augmentClass = Super.augmentClass; PooledClass.addPoolingTo(Class, PooledClass.threeArgumentPooler);
};
PooledClass.addPoolingTo(SyntheticEvent, PooledClass.threeArgumentPooler);
module.exports = SyntheticEvent;
},{“./PooledClass”:25,“./emptyFunction”:109,“./getEventTarget”:117,“./merge”:134,“./mergeInto”:136}],90:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule SyntheticFocusEvent * @typechecks static-only */
“use strict”;
var SyntheticUIEvent = dereq(“./SyntheticUIEvent”);
/**
* @interface FocusEvent * @see http://www.w3.org/TR/DOM-Level-3-Events/ */
var FocusEventInterface = {
relatedTarget: null
};
/**
* @param {object} dispatchConfig Configuration used to dispatch this event. * @param {string} dispatchMarker Marker identifying the event target. * @param {object} nativeEvent Native browser event. * @extends {SyntheticUIEvent} */
function SyntheticFocusEvent(dispatchConfig, dispatchMarker, nativeEvent) {
SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
}
SyntheticUIEvent.augmentClass(SyntheticFocusEvent, FocusEventInterface);
module.exports = SyntheticFocusEvent;
},{“./SyntheticUIEvent”:94}],91:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule SyntheticKeyboardEvent * @typechecks static-only */
“use strict”;
var SyntheticUIEvent = dereq(“./SyntheticUIEvent”);
var getEventKey = dereq(“./getEventKey”);
/**
* @interface KeyboardEvent * @see http://www.w3.org/TR/DOM-Level-3-Events/ */
var KeyboardEventInterface = {
key: getEventKey, location: null, ctrlKey: null, shiftKey: null, altKey: null, metaKey: null, repeat: null, locale: null, // Legacy Interface 'char': null, charCode: null, keyCode: null, which: null
};
/**
* @param {object} dispatchConfig Configuration used to dispatch this event. * @param {string} dispatchMarker Marker identifying the event target. * @param {object} nativeEvent Native browser event. * @extends {SyntheticUIEvent} */
function SyntheticKeyboardEvent(dispatchConfig, dispatchMarker, nativeEvent) {
SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
}
SyntheticUIEvent.augmentClass(SyntheticKeyboardEvent, KeyboardEventInterface);
module.exports = SyntheticKeyboardEvent;
},{“./SyntheticUIEvent”:94,“./getEventKey”:116}],92:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule SyntheticMouseEvent * @typechecks static-only */
“use strict”;
var SyntheticUIEvent = dereq(“./SyntheticUIEvent”); var ViewportMetrics = dereq(“./ViewportMetrics”);
/**
* @interface MouseEvent * @see http://www.w3.org/TR/DOM-Level-3-Events/ */
var MouseEventInterface = {
screenX: null, screenY: null, clientX: null, clientY: null, ctrlKey: null, shiftKey: null, altKey: null, metaKey: null, button: function(event) { // Webkit, Firefox, IE9+ // which: 1 2 3 // button: 0 1 2 (standard) var button = event.button; if ('which' in event) { return button; } // IE<9 // which: undefined // button: 0 0 0 // button: 1 4 2 (onmouseup) return button === 2 ? 2 : button === 4 ? 1 : 0; }, buttons: null, relatedTarget: function(event) { return event.relatedTarget || ( event.fromElement === event.srcElement ? event.toElement : event.fromElement ); }, // "Proprietary" Interface. pageX: function(event) { return 'pageX' in event ? event.pageX : event.clientX + ViewportMetrics.currentScrollLeft; }, pageY: function(event) { return 'pageY' in event ? event.pageY : event.clientY + ViewportMetrics.currentScrollTop; }
};
/**
* @param {object} dispatchConfig Configuration used to dispatch this event. * @param {string} dispatchMarker Marker identifying the event target. * @param {object} nativeEvent Native browser event. * @extends {SyntheticUIEvent} */
function SyntheticMouseEvent(dispatchConfig, dispatchMarker, nativeEvent) {
SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
}
SyntheticUIEvent.augmentClass(SyntheticMouseEvent, MouseEventInterface);
module.exports = SyntheticMouseEvent;
},{“./SyntheticUIEvent”:94,“./ViewportMetrics”:97}],93:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule SyntheticTouchEvent * @typechecks static-only */
“use strict”;
var SyntheticUIEvent = dereq(“./SyntheticUIEvent”);
/**
* @interface TouchEvent * @see http://www.w3.org/TR/touch-events/ */
var TouchEventInterface = {
touches: null, targetTouches: null, changedTouches: null, altKey: null, metaKey: null, ctrlKey: null, shiftKey: null
};
/**
* @param {object} dispatchConfig Configuration used to dispatch this event. * @param {string} dispatchMarker Marker identifying the event target. * @param {object} nativeEvent Native browser event. * @extends {SyntheticUIEvent} */
function SyntheticTouchEvent(dispatchConfig, dispatchMarker, nativeEvent) {
SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
}
SyntheticUIEvent.augmentClass(SyntheticTouchEvent, TouchEventInterface);
module.exports = SyntheticTouchEvent;
},{“./SyntheticUIEvent”:94}],94:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule SyntheticUIEvent * @typechecks static-only */
“use strict”;
var SyntheticEvent = dereq(“./SyntheticEvent”);
/**
* @interface UIEvent * @see http://www.w3.org/TR/DOM-Level-3-Events/ */
var UIEventInterface = {
view: null, detail: null
};
/**
* @param {object} dispatchConfig Configuration used to dispatch this event. * @param {string} dispatchMarker Marker identifying the event target. * @param {object} nativeEvent Native browser event. * @extends {SyntheticEvent} */
function SyntheticUIEvent(dispatchConfig, dispatchMarker, nativeEvent) {
SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
}
SyntheticEvent.augmentClass(SyntheticUIEvent, UIEventInterface);
module.exports = SyntheticUIEvent;
},{“./SyntheticEvent”:89}],95:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule SyntheticWheelEvent * @typechecks static-only */
“use strict”;
var SyntheticMouseEvent = dereq(“./SyntheticMouseEvent”);
/**
* @interface WheelEvent * @see http://www.w3.org/TR/DOM-Level-3-Events/ */
var WheelEventInterface = {
deltaX: function(event) { return ( 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive). 'wheelDeltaX' in event ? -event.wheelDeltaX : 0 ); }, deltaY: function(event) { return ( 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive). 'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive). 'wheelDelta' in event ? -event.wheelDelta : 0 ); }, deltaZ: null, // Browsers without "deltaMode" is reporting in raw wheel delta where one // notch on the scroll is always +/- 120, roughly equivalent to pixels. // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size. deltaMode: null
};
/**
* @param {object} dispatchConfig Configuration used to dispatch this event. * @param {string} dispatchMarker Marker identifying the event target. * @param {object} nativeEvent Native browser event. * @extends {SyntheticMouseEvent} */
function SyntheticWheelEvent(dispatchConfig, dispatchMarker, nativeEvent) {
SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent);
}
SyntheticMouseEvent.augmentClass(SyntheticWheelEvent, WheelEventInterface);
module.exports = SyntheticWheelEvent;
},{“./SyntheticMouseEvent”:92}],96:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule Transaction */
“use strict”;
var invariant = dereq(“./invariant”);
/**
* `Transaction` creates a black box that is able to wrap any method such that * certain invariants are maintained before and after the method is invoked * (Even if an exception is thrown while invoking the wrapped method). Whoever * instantiates a transaction can provide enforcers of the invariants at * creation time. The `Transaction` class itself will supply one additional * automatic invariant for you - the invariant that any transaction instance * should not be run while it is already being run. You would typically create a * single instance of a `Transaction` for reuse multiple times, that potentially * is used to wrap several different methods. Wrappers are extremely simple - * they only require implementing two methods. * * <pre> * wrappers (injected at creation time) * + + * | | * +-----------------|--------|--------------+ * | v | | * | +---------------+ | | * | +--| wrapper1 |---|----+ | * | | +---------------+ v | | * | | +-------------+ | | * | | +----| wrapper2 |--------+ | * | | | +-------------+ | | | * | | | | | | * | v v v v | wrapper * | +---+ +---+ +---------+ +---+ +---+ | invariants * perform(anyMethod) | | | | | | | | | | | | maintained * +----------------->|-|---|-|---|-->|anyMethod|---|---|-|---|-|--------> * | | | | | | | | | | | | * | | | | | | | | | | | | * | | | | | | | | | | | | * | +---+ +---+ +---------+ +---+ +---+ | * | initialize close | * +-----------------------------------------+ * </pre> * * Bonus: * - Reports timing metrics by method name and wrapper index. * * Use cases: * - Preserving the input selection ranges before/after reconciliation. * Restoring selection even in the event of an unexpected error. * - Deactivating events while rearranging the DOM, preventing blurs/focuses, * while guaranteeing that afterwards, the event system is reactivated. * - Flushing a queue of collected DOM mutations to the main UI thread after a * reconciliation takes place in a worker thread. * - Invoking any collected `componentDidUpdate` callbacks after rendering new * content. * - (Future use case): Wrapping particular flushes of the `ReactWorker` queue * to preserve the `scrollTop` (an automatic scroll aware DOM). * - (Future use case): Layout calculations before and after DOM upates. * * Transactional plugin API: * - A module that has an `initialize` method that returns any precomputation. * - and a `close` method that accepts the precomputation. `close` is invoked * when the wrapped process is completed, or has failed. * * @param {Array<TransactionalWrapper>} transactionWrapper Wrapper modules * that implement `initialize` and `close`. * @return {Transaction} Single transaction for reuse in thread. * * @class Transaction */
var Mixin = {
/** * Sets up this instance so that it is prepared for collecting metrics. Does * so such that this setup method may be used on an instance that is already * initialized, in a way that does not consume additional memory upon reuse. * That can be useful if you decide to make your subclass of this mixin a * "PooledClass". */ reinitializeTransaction: function() { this.transactionWrappers = this.getTransactionWrappers(); if (!this.wrapperInitData) { this.wrapperInitData = []; } else { this.wrapperInitData.length = 0; } if (!this.timingMetrics) { this.timingMetrics = {}; } this.timingMetrics.methodInvocationTime = 0; if (!this.timingMetrics.wrapperInitTimes) { this.timingMetrics.wrapperInitTimes = []; } else { this.timingMetrics.wrapperInitTimes.length = 0; } if (!this.timingMetrics.wrapperCloseTimes) { this.timingMetrics.wrapperCloseTimes = []; } else { this.timingMetrics.wrapperCloseTimes.length = 0; } this._isInTransaction = false; }, _isInTransaction: false, /** * @abstract * @return {Array<TransactionWrapper>} Array of transaction wrappers. */ getTransactionWrappers: null, isInTransaction: function() { return !!this._isInTransaction; }, /** * Executes the function within a safety window. Use this for the top level * methods that result in large amounts of computation/mutations that would * need to be safety checked. * * @param {function} method Member of scope to call. * @param {Object} scope Scope to invoke from. * @param {Object?=} args... Arguments to pass to the method (optional). * Helps prevent need to bind in many cases. * @return Return value from `method`. */ perform: function(method, scope, a, b, c, d, e, f) { ("production" !== "development" ? invariant( !this.isInTransaction(), 'Transaction.perform(...): Cannot initialize a transaction when there ' + 'is already an outstanding transaction.' ) : invariant(!this.isInTransaction())); var memberStart = Date.now(); var errorThrown; var ret; try { this._isInTransaction = true; // Catching errors makes debugging more difficult, so we start with // errorThrown set to true before setting it to false after calling // close -- if it's still set to true in the finally block, it means // one of these calls threw. errorThrown = true; this.initializeAll(0); ret = method.call(scope, a, b, c, d, e, f); errorThrown = false; } finally { var memberEnd = Date.now(); this.methodInvocationTime += (memberEnd - memberStart); try { if (errorThrown) { // If `method` throws, prefer to show that stack trace over any thrown // by invoking `closeAll`. try { this.closeAll(0); } catch (err) { } } else { // Since `method` didn't throw, we don't want to silence the exception // here. this.closeAll(0); } } finally { this._isInTransaction = false; } } return ret; }, initializeAll: function(startIndex) { var transactionWrappers = this.transactionWrappers; var wrapperInitTimes = this.timingMetrics.wrapperInitTimes; for (var i = startIndex; i < transactionWrappers.length; i++) { var initStart = Date.now(); var wrapper = transactionWrappers[i]; try { // Catching errors makes debugging more difficult, so we start with the // OBSERVED_ERROR state before overwriting it with the real return value // of initialize -- if it's still set to OBSERVED_ERROR in the finally // block, it means wrapper.initialize threw. this.wrapperInitData[i] = Transaction.OBSERVED_ERROR; this.wrapperInitData[i] = wrapper.initialize ? wrapper.initialize.call(this) : null; } finally { var curInitTime = wrapperInitTimes[i]; var initEnd = Date.now(); wrapperInitTimes[i] = (curInitTime || 0) + (initEnd - initStart); if (this.wrapperInitData[i] === Transaction.OBSERVED_ERROR) { // The initializer for wrapper i threw an error; initialize the // remaining wrappers but silence any exceptions from them to ensure // that the first error is the one to bubble up. try { this.initializeAll(i + 1); } catch (err) { } } } } }, /** * Invokes each of `this.transactionWrappers.close[i]` functions, passing into * them the respective return values of `this.transactionWrappers.init[i]` * (`close`rs that correspond to initializers that failed will not be * invoked). */ closeAll: function(startIndex) { ("production" !== "development" ? invariant( this.isInTransaction(), 'Transaction.closeAll(): Cannot close transaction when none are open.' ) : invariant(this.isInTransaction())); var transactionWrappers = this.transactionWrappers; var wrapperCloseTimes = this.timingMetrics.wrapperCloseTimes; for (var i = startIndex; i < transactionWrappers.length; i++) { var wrapper = transactionWrappers[i]; var closeStart = Date.now(); var initData = this.wrapperInitData[i]; var errorThrown; try { // Catching errors makes debugging more difficult, so we start with // errorThrown set to true before setting it to false after calling // close -- if it's still set to true in the finally block, it means // wrapper.close threw. errorThrown = true; if (initData !== Transaction.OBSERVED_ERROR) { wrapper.close && wrapper.close.call(this, initData); } errorThrown = false; } finally { var closeEnd = Date.now(); var curCloseTime = wrapperCloseTimes[i]; wrapperCloseTimes[i] = (curCloseTime || 0) + (closeEnd - closeStart); if (errorThrown) { // The closer for wrapper i threw an error; close the remaining // wrappers but silence any exceptions from them to ensure that the // first error is the one to bubble up. try { this.closeAll(i + 1); } catch (e) { } } } } this.wrapperInitData.length = 0; }
};
var Transaction = {
Mixin: Mixin, /** * Token to look for to determine if an error occured. */ OBSERVED_ERROR: {}
};
module.exports = Transaction;
},{“./invariant”:125}],97:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule ViewportMetrics */
“use strict”;
var getUnboundedScrollPosition = dereq(“./getUnboundedScrollPosition”);
var ViewportMetrics = {
currentScrollLeft: 0, currentScrollTop: 0, refreshScrollValues: function() { var scrollPosition = getUnboundedScrollPosition(window); ViewportMetrics.currentScrollLeft = scrollPosition.x; ViewportMetrics.currentScrollTop = scrollPosition.y; }
};
module.exports = ViewportMetrics;
},{“./getUnboundedScrollPosition”:122}],98:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule accumulate */
“use strict”;
var invariant = dereq(“./invariant”);
/**
* Accumulates items that must not be null or undefined. * * This is used to conserve memory by avoiding array allocations. * * @return {*|array<*>} An accumulation of items. */
function accumulate(current, next) {
("production" !== "development" ? invariant( next != null, 'accumulate(...): Accumulated items must be not be null or undefined.' ) : invariant(next != null)); if (current == null) { return next; } else { // Both are not empty. Warning: Never call x.concat(y) when you are not // certain that x is an Array (x could be a string with concat method). var currentIsArray = Array.isArray(current); var nextIsArray = Array.isArray(next); if (currentIsArray) { return current.concat(next); } else { if (nextIsArray) { return [current].concat(next); } else { return [current, next]; } } }
}
module.exports = accumulate;
},{“./invariant”:125}],99:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule adler32 */
/* jslint bitwise:true */
“use strict”;
var MOD = 65521;
// This is a clean-room implementation of adler32 designed for detecting // if markup is not what we expect it to be. It does not need to be // cryptographically strong, only reasonable good at detecting if markup // generated on the server is different than that on the client. function adler32(data) {
var a = 1; var b = 0; for (var i = 0; i < data.length; i++) { a = (a + data.charCodeAt(i)) % MOD; b = (b + a) % MOD; } return a | (b << 16);
}
module.exports = adler32;
},{}],100:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @typechecks * @providesModule cloneWithProps */
“use strict”;
var ReactPropTransferer = dereq(“./ReactPropTransferer”);
var keyOf = dereq(“./keyOf”); var warning = dereq(“./warning”);
var CHILDREN_PROP = keyOf({children: null});
/**
* Sometimes you want to change the props of a child passed to you. Usually * this is to add a CSS class. * * @param {object} child child component you'd like to clone * @param {object} props props you'd like to modify. They will be merged * as if you used `transferPropsTo()`. * @return {object} a clone of child with props merged in. */
function cloneWithProps(child, props) {
if ("production" !== "development") { ("production" !== "development" ? warning( !child.props.ref, 'You are calling cloneWithProps() on a child with a ref. This is ' + 'dangerous because you\'re creating a new child which will not be ' + 'added as a ref to its parent.' ) : null); } var newProps = ReactPropTransferer.mergeProps(props, child.props); // Use `child.props.children` if it is provided. if (!newProps.hasOwnProperty(CHILDREN_PROP) && child.props.hasOwnProperty(CHILDREN_PROP)) { newProps.children = child.props.children; } return child.constructor.ConvenienceConstructor(newProps);
}
module.exports = cloneWithProps;
},{“./ReactPropTransferer”:66,“./keyOf”:132,“./warning”:148}],101:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule containsNode * @typechecks */
var isTextNode = dereq(“./isTextNode”);
/*jslint bitwise:true */
/**
* Checks if a given DOM node contains or is another DOM node. * * @param {?DOMNode} outerNode Outer DOM node. * @param {?DOMNode} innerNode Inner DOM node. * @return {boolean} True if `outerNode` contains or is `innerNode`. */
function containsNode(outerNode, innerNode) {
if (!outerNode || !innerNode) { return false; } else if (outerNode === innerNode) { return true; } else if (isTextNode(outerNode)) { return false; } else if (isTextNode(innerNode)) { return containsNode(outerNode, innerNode.parentNode); } else if (outerNode.contains) { return outerNode.contains(innerNode); } else if (outerNode.compareDocumentPosition) { return !!(outerNode.compareDocumentPosition(innerNode) & 16); } else { return false; }
}
module.exports = containsNode;
},{“./isTextNode”:129}],102:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule copyProperties */
/**
* Copy properties from one or more objects (up to 5) into the first object. * This is a shallow copy. It mutates the first object and also returns it. * * NOTE: `arguments` has a very significant performance penalty, which is why * we don't support unlimited arguments. */
function copyProperties(obj, a, b, c, d, e, f) {
obj = obj || {}; if ("production" !== "development") { if (f) { throw new Error('Too many arguments passed to copyProperties'); } } var args = [a, b, c, d, e]; var ii = 0, v; while (args[ii]) { v = args[ii++]; for (var k in v) { obj[k] = v[k]; } // IE ignores toString in object iteration.. See: // webreflection.blogspot.com/2007/07/quick-fix-internet-explorer-and.html if (v.hasOwnProperty && v.hasOwnProperty('toString') && (typeof v.toString != 'undefined') && (obj.toString !== v.toString)) { obj.toString = v.toString; } } return obj;
}
module.exports = copyProperties;
},{}],103:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule createArrayFrom * @typechecks */
var toArray = dereq(“./toArray”);
/**
* Perform a heuristic test to determine if an object is "array-like". * * A monk asked Joshu, a Zen master, "Has a dog Buddha nature?" * Joshu replied: "Mu." * * This function determines if its argument has "array nature": it returns * true if the argument is an actual array, an `arguments' object, or an * HTMLCollection (e.g. node.childNodes or node.getElementsByTagName()). * * It will return false for other array-like objects like Filelist. * * @param {*} obj * @return {boolean} */
function hasArrayNature(obj) {
return ( // not null/false !!obj && // arrays are objects, NodeLists are functions in Safari (typeof obj == 'object' || typeof obj == 'function') && // quacks like an array ('length' in obj) && // not window !('setInterval' in obj) && // no DOM node should be considered an array-like // a 'select' element has 'length' and 'item' properties on IE8 (typeof obj.nodeType != 'number') && ( // a real array (// HTMLCollection/NodeList (Array.isArray(obj) || // arguments ('callee' in obj) || 'item' in obj)) ) );
}
/**
* Ensure that the argument is an array by wrapping it in an array if it is not. * Creates a copy of the argument if it is already an array. * * This is mostly useful idiomatically: * * var createArrayFrom = require('createArrayFrom'); * * function takesOneOrMoreThings(things) { * things = createArrayFrom(things); * ... * } * * This allows you to treat `things' as an array, but accept scalars in the API. * * If you need to convert an array-like object, like `arguments`, into an array * use toArray instead. * * @param {*} obj * @return {array} */
function createArrayFrom(obj) {
if (!hasArrayNature(obj)) { return [obj]; } else if (Array.isArray(obj)) { return obj.slice(); } else { return toArray(obj); }
}
module.exports = createArrayFrom;
},{“./toArray”:145}],104:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule createFullPageComponent * @typechecks */
“use strict”;
// Defeat circular references by requiring this directly. var ReactCompositeComponent = dereq(“./ReactCompositeComponent”);
var invariant = dereq(“./invariant”);
/**
* Create a component that will throw an exception when unmounted. * * Components like <html> <head> and <body> can't be removed or added * easily in a cross-browser way, however it's valuable to be able to * take advantage of React's reconciliation for styling and <title> * management. So we just document it and throw in dangerous cases. * * @param {function} componentClass convenience constructor to wrap * @return {function} convenience constructor of new component */
function createFullPageComponent(componentClass) {
var FullPageComponent = ReactCompositeComponent.createClass({ displayName: 'ReactFullPageComponent' + ( componentClass.componentConstructor.displayName || '' ), componentWillUnmount: function() { ("production" !== "development" ? invariant( false, '%s tried to unmount. Because of cross-browser quirks it is ' + 'impossible to unmount some top-level components (eg <html>, <head>, ' + 'and <body>) reliably and efficiently. To fix this, have a single ' + 'top-level component that never unmounts render these elements.', this.constructor.displayName ) : invariant(false)); }, render: function() { return this.transferPropsTo(componentClass(null, this.props.children)); } }); return FullPageComponent;
}
module.exports = createFullPageComponent;
},{“./ReactCompositeComponent”:33,“./invariant”:125}],105:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule createNodesFromMarkup * @typechecks */
/*jslint evil: true, sub: true */
var ExecutionEnvironment = dereq(“./ExecutionEnvironment”);
var createArrayFrom = dereq(“./createArrayFrom”); var getMarkupWrap = dereq(“./getMarkupWrap”); var invariant = dereq(“./invariant”);
/**
* Dummy container used to render all markup. */
var dummyNode =
ExecutionEnvironment.canUseDOM ? document.createElement('div') : null;
/**
* Pattern used by `getNodeName`. */
var nodeNamePattern = /^s*<(w+)/;
/**
* Extracts the `nodeName` of the first element in a string of markup. * * @param {string} markup String of markup. * @return {?string} Node name of the supplied markup. */
function getNodeName(markup) {
var nodeNameMatch = markup.match(nodeNamePattern); return nodeNameMatch && nodeNameMatch[1].toLowerCase();
}
/**
* Creates an array containing the nodes rendered from the supplied markup. The * optionally supplied `handleScript` function will be invoked once for each * <script> element that is rendered. If no `handleScript` function is supplied, * an exception is thrown if any <script> elements are rendered. * * @param {string} markup A string of valid HTML markup. * @param {?function} handleScript Invoked once for each rendered <script>. * @return {array<DOMElement|DOMTextNode>} An array of rendered nodes. */
function createNodesFromMarkup(markup, handleScript) {
var node = dummyNode; ("production" !== "development" ? invariant(!!dummyNode, 'createNodesFromMarkup dummy not initialized') : invariant(!!dummyNode)); var nodeName = getNodeName(markup); var wrap = nodeName && getMarkupWrap(nodeName); if (wrap) { node.innerHTML = wrap[1] + markup + wrap[2]; var wrapDepth = wrap[0]; while (wrapDepth--) { node = node.lastChild; } } else { node.innerHTML = markup; } var scripts = node.getElementsByTagName('script'); if (scripts.length) { ("production" !== "development" ? invariant( handleScript, 'createNodesFromMarkup(...): Unexpected <script> element rendered.' ) : invariant(handleScript)); createArrayFrom(scripts).forEach(handleScript); } var nodes = createArrayFrom(node.childNodes); while (node.lastChild) { node.removeChild(node.lastChild); } return nodes;
}
module.exports = createNodesFromMarkup;
},{“./ExecutionEnvironment”:21,“./createArrayFrom”:103,“./getMarkupWrap”:118,“./invariant”:125}],106:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule createObjectFrom */
/**
* Construct an object from an array of keys * and optionally specified value or list of values. * * >>> createObjectFrom(['a','b','c']); * {a: true, b: true, c: true} * * >>> createObjectFrom(['a','b','c'], false); * {a: false, b: false, c: false} * * >>> createObjectFrom(['a','b','c'], 'monkey'); * {c:'monkey', b:'monkey' c:'monkey'} * * >>> createObjectFrom(['a','b','c'], [1,2,3]); * {a: 1, b: 2, c: 3} * * >>> createObjectFrom(['women', 'men'], [true, false]); * {women: true, men: false} * * @param Array list of keys * @param mixed optional value or value array. defaults true. * @returns object */
function createObjectFrom(keys, values /* = true */) {
if ("production" !== "development") { if (!Array.isArray(keys)) { throw new TypeError('Must pass an array of keys.'); } } var object = {}; var isArray = Array.isArray(values); if (typeof values == 'undefined') { values = true; } for (var ii = keys.length; ii--;) { object[keys[ii]] = isArray ? values[ii] : values; } return object;
}
module.exports = createObjectFrom;
},{}],107:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule cx */
/**
* This function is used to mark string literals representing CSS class names * so that they can be transformed statically. This allows for modularization * and minification of CSS class names. * * In static_upstream, this function is actually implemented, but it should * eventually be replaced with something more descriptive, and the transform * that is used in the main stack should be ported for use elsewhere. * * @param string|object className to modularize, or an object of key/values. * In the object case, the values are conditions that * determine if the className keys should be included. * @param [string ...] Variable list of classNames in the string case. * @return string Renderable space-separated CSS className. */
function cx(classNames) {
if (typeof classNames == 'object') { return Object.keys(classNames).filter(function(className) { return classNames[className]; }).join(' '); } else { return Array.prototype.join.call(arguments, ' '); }
}
module.exports = cx;
},{}],108:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule dangerousStyleValue * @typechecks static-only */
“use strict”;
var CSSProperty = dereq(“./CSSProperty”);
/**
* Convert a value into the proper css writable value. The `styleName` name * name should be logical (no hyphens), as specified * in `CSSProperty.isUnitlessNumber`. * * @param {string} styleName CSS property name such as `topMargin`. * @param {*} value CSS property value such as `10px`. * @return {string} Normalized style value with dimensions applied. */
function dangerousStyleValue(styleName, value) {
// Note that we've removed escapeTextForBrowser() calls here since the // whole string will be escaped when the attribute is injected into // the markup. If you provide unsafe user data here they can inject // arbitrary CSS which may be problematic (I couldn't repro this): // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/ // This is not an XSS hole but instead a potential CSS injection issue // which has lead to a greater discussion about how we're going to // trust URLs moving forward. See #2115901 var isEmpty = value == null || typeof value === 'boolean' || value === ''; if (isEmpty) { return ''; } var isNonNumeric = isNaN(value); if (isNonNumeric || value === 0 || CSSProperty.isUnitlessNumber[styleName]) { return '' + value; // cast to string } return value + 'px';
}
module.exports = dangerousStyleValue;
},{“./CSSProperty”:3}],109:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule emptyFunction */
var copyProperties = dereq(“./copyProperties”);
function makeEmptyFunction(arg) {
return function() { return arg; };
}
/**
* This function accepts and discards inputs; it has no side effects. This is * primarily useful idiomatically for overridable function endpoints which * always need to be callable, since JS lacks a null-call idiom ala Cocoa. */
function emptyFunction() {}
copyProperties(emptyFunction, {
thatReturns: makeEmptyFunction, thatReturnsFalse: makeEmptyFunction(false), thatReturnsTrue: makeEmptyFunction(true), thatReturnsNull: makeEmptyFunction(null), thatReturnsThis: function() { return this; }, thatReturnsArgument: function(arg) { return arg; }
});
module.exports = emptyFunction;
},{“./copyProperties”:102}],110:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule emptyObject */
“use strict”;
var emptyObject = {};
if (“production” !== “development”) {
Object.freeze(emptyObject);
}
module.exports = emptyObject;
},{}],111:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule escapeTextForBrowser * @typechecks static-only */
“use strict”;
var ESCAPE_LOOKUP = {
"&": "&", ">": ">", "<": "<", "\"": """, "'": "'", "/": "/"
};
var ESCAPE_REGEX = /[&><“'/]/g;
function escaper(match) {
return ESCAPE_LOOKUP[match];
}
/**
* Escapes text to prevent scripting attacks. * * @param {*} text Text value to escape. * @return {string} An escaped string. */
function escapeTextForBrowser(text) {
return ('' + text).replace(ESCAPE_REGEX, escaper);
}
module.exports = escapeTextForBrowser;
},{}],112:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule flattenChildren */
“use strict”;
var invariant = dereq(“./invariant”); var traverseAllChildren = dereq(“./traverseAllChildren”);
/**
* @param {function} traverseContext Context passed through traversal. * @param {?ReactComponent} child React child component. * @param {!string} name String name of key path to child. */
function flattenSingleChildIntoContext(traverseContext, child, name) {
// We found a component instance. var result = traverseContext; ("production" !== "development" ? invariant( !result.hasOwnProperty(name), 'flattenChildren(...): Encountered two children with the same key, `%s`. ' + 'Children keys must be unique.', name ) : invariant(!result.hasOwnProperty(name))); if (child != null) { result[name] = child; }
}
/**
* Flattens children that are typically specified as `props.children`. Any null * children will not be included in the resulting object. * @return {!object} flattened children keyed by name. */
function flattenChildren(children) {
if (children == null) { return children; } var result = {}; traverseAllChildren(children, flattenSingleChildIntoContext, result); return result;
}
module.exports = flattenChildren;
},{“./invariant”:125,“./traverseAllChildren”:146}],113:[function(dereq,module,exports){ /**
* Copyright 2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule focusNode */
“use strict”;
/**
* IE8 throws if an input/textarea is disabled and we try to focus it. * Focus only when necessary. * * @param {DOMElement} node input/textarea to focus */
function focusNode(node) {
if (!node.disabled) { node.focus(); }
}
module.exports = focusNode;
},{}],114:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule forEachAccumulated */
“use strict”;
/**
* @param {array} an "accumulation" of items which is either an Array or * a single item. Useful when paired with the `accumulate` module. This is a * simple utility that allows us to reason about a collection of items, but * handling the case when there is exactly one item (and we do not need to * allocate an array). */
var forEachAccumulated = function(arr, cb, scope) {
if (Array.isArray(arr)) { arr.forEach(cb, scope); } else if (arr) { cb.call(scope, arr); }
};
module.exports = forEachAccumulated;
},{}],115:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule getActiveElement * @typechecks */
/**
* Same as document.activeElement but wraps in a try-catch block. In IE it is * not safe to call document.activeElement if there is nothing focused. * * The activeElement will be null only if the document body is not yet defined. */
function getActiveElement() /*?DOMElement*/ {
try { return document.activeElement || document.body; } catch (e) { return document.body; }
}
module.exports = getActiveElement;
},{}],116:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule getEventKey * @typechecks static-only */
“use strict”;
/**
* Normalization of deprecated HTML5 "key" values * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names */
var normalizeKey = {
'Esc': 'Escape', 'Spacebar': ' ', 'Left': 'ArrowLeft', 'Up': 'ArrowUp', 'Right': 'ArrowRight', 'Down': 'ArrowDown', 'Del': 'Delete', 'Win': 'OS', 'Menu': 'ContextMenu', 'Apps': 'ContextMenu', 'Scroll': 'ScrollLock', 'MozPrintableKey': 'Unidentified'
};
/**
* Translation from legacy "which/keyCode" to HTML5 "key" * Only special keys supported, all others depend on keyboard layout or browser * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names */
var translateToKey = {
8: 'Backspace', 9: 'Tab', 12: 'Clear', 13: 'Enter', 16: 'Shift', 17: 'Control', 18: 'Alt', 19: 'Pause', 20: 'CapsLock', 27: 'Escape', 32: ' ', 33: 'PageUp', 34: 'PageDown', 35: 'End', 36: 'Home', 37: 'ArrowLeft', 38: 'ArrowUp', 39: 'ArrowRight', 40: 'ArrowDown', 45: 'Insert', 46: 'Delete', 112: 'F1', 113: 'F2', 114: 'F3', 115: 'F4', 116: 'F5', 117: 'F6', 118: 'F7', 119: 'F8', 120: 'F9', 121: 'F10', 122: 'F11', 123: 'F12', 144: 'NumLock', 145: 'ScrollLock', 224: 'Meta'
};
/**
* @param {object} nativeEvent Native browser event. * @return {string} Normalized `key` property. */
function getEventKey(nativeEvent) {
return 'key' in nativeEvent ? normalizeKey[nativeEvent.key] || nativeEvent.key : translateToKey[nativeEvent.which || nativeEvent.keyCode] || 'Unidentified';
}
module.exports = getEventKey;
},{}],117:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule getEventTarget * @typechecks static-only */
“use strict”;
/**
* Gets the target node from a native browser event by accounting for * inconsistencies in browser DOM APIs. * * @param {object} nativeEvent Native browser event. * @return {DOMEventTarget} Target node. */
function getEventTarget(nativeEvent) {
var target = nativeEvent.target || nativeEvent.srcElement || window; // Safari may fire events on text nodes (Node.TEXT_NODE is 3). // @see http://www.quirksmode.org/js/events_properties.html return target.nodeType === 3 ? target.parentNode : target;
}
module.exports = getEventTarget;
},{}],118:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule getMarkupWrap */
var ExecutionEnvironment = dereq(“./ExecutionEnvironment”);
var invariant = dereq(“./invariant”);
/**
* Dummy container used to detect which wraps are necessary. */
var dummyNode =
ExecutionEnvironment.canUseDOM ? document.createElement('div') : null;
/**
* Some browsers cannot use `innerHTML` to render certain elements standalone, * so we wrap them, render the wrapped nodes, then extract the desired node. * * In IE8, certain elements cannot render alone, so wrap all elements ('*'). */
var shouldWrap = {
// Force wrapping for SVG elements because if they get created inside a <div>, // they will be initialized in the wrong namespace (and will not display). 'circle': true, 'defs': true, 'g': true, 'line': true, 'linearGradient': true, 'path': true, 'polygon': true, 'polyline': true, 'radialGradient': true, 'rect': true, 'stop': true, 'text': true
};
var selectWrap = [1, '<select multiple=“true”>', '</select>']; var tableWrap = [1, '<table>', '</table>']; var trWrap = [3, '<table><tbody><tr>', '</tr></tbody></table>'];
var svgWrap = [1, '<svg>', '</svg>'];
var markupWrap = {
'*': [1, '?<div>', '</div>'], 'area': [1, '<map>', '</map>'], 'col': [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'], 'legend': [1, '<fieldset>', '</fieldset>'], 'param': [1, '<object>', '</object>'], 'tr': [2, '<table><tbody>', '</tbody></table>'], 'optgroup': selectWrap, 'option': selectWrap, 'caption': tableWrap, 'colgroup': tableWrap, 'tbody': tableWrap, 'tfoot': tableWrap, 'thead': tableWrap, 'td': trWrap, 'th': trWrap, 'circle': svgWrap, 'defs': svgWrap, 'g': svgWrap, 'line': svgWrap, 'linearGradient': svgWrap, 'path': svgWrap, 'polygon': svgWrap, 'polyline': svgWrap, 'radialGradient': svgWrap, 'rect': svgWrap, 'stop': svgWrap, 'text': svgWrap
};
/**
* Gets the markup wrap configuration for the supplied `nodeName`. * * NOTE: This lazily detects which wraps are necessary for the current browser. * * @param {string} nodeName Lowercase `nodeName`. * @return {?array} Markup wrap configuration, if applicable. */
function getMarkupWrap(nodeName) {
("production" !== "development" ? invariant(!!dummyNode, 'Markup wrapping node not initialized') : invariant(!!dummyNode)); if (!markupWrap.hasOwnProperty(nodeName)) { nodeName = '*'; } if (!shouldWrap.hasOwnProperty(nodeName)) { if (nodeName === '*') { dummyNode.innerHTML = '<link />'; } else { dummyNode.innerHTML = '<' + nodeName + '></' + nodeName + '>'; } shouldWrap[nodeName] = !dummyNode.firstChild; } return shouldWrap[nodeName] ? markupWrap[nodeName] : null;
}
module.exports = getMarkupWrap;
},{“./ExecutionEnvironment”:21,“./invariant”:125}],119:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule getNodeForCharacterOffset */
“use strict”;
/**
* Given any node return the first leaf node without children. * * @param {DOMElement|DOMTextNode} node * @return {DOMElement|DOMTextNode} */
function getLeafNode(node) {
while (node && node.firstChild) { node = node.firstChild; } return node;
}
/**
* Get the next sibling within a container. This will walk up the * DOM if a node's siblings have been exhausted. * * @param {DOMElement|DOMTextNode} node * @return {?DOMElement|DOMTextNode} */
function getSiblingNode(node) {
while (node) { if (node.nextSibling) { return node.nextSibling; } node = node.parentNode; }
}
/**
* Get object describing the nodes which contain characters at offset. * * @param {DOMElement|DOMTextNode} root * @param {number} offset * @return {?object} */
function getNodeForCharacterOffset(root, offset) {
var node = getLeafNode(root); var nodeStart = 0; var nodeEnd = 0; while (node) { if (node.nodeType == 3) { nodeEnd = nodeStart + node.textContent.length; if (nodeStart <= offset && nodeEnd >= offset) { return { node: node, offset: offset - nodeStart }; } nodeStart = nodeEnd; } node = getLeafNode(getSiblingNode(node)); }
}
module.exports = getNodeForCharacterOffset;
},{}],120:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule getReactRootElementInContainer */
“use strict”;
var DOC_NODE_TYPE = 9;
/**
* @param {DOMElement|DOMDocument} container DOM element that may contain * a React component * @return {?*} DOM element that may have the reactRoot ID, or null. */
function getReactRootElementInContainer(container) {
if (!container) { return null; } if (container.nodeType === DOC_NODE_TYPE) { return container.documentElement; } else { return container.firstChild; }
}
module.exports = getReactRootElementInContainer;
},{}],121:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule getTextContentAccessor */
“use strict”;
var ExecutionEnvironment = dereq(“./ExecutionEnvironment”);
var contentKey = null;
/**
* Gets the key used to access text content on a DOM node. * * @return {?string} Key used to access text content. * @internal */
function getTextContentAccessor() {
if (!contentKey && ExecutionEnvironment.canUseDOM) { // Prefer textContent to innerText because many browsers support both but // SVG <text> elements don't support innerText even when <div> does. contentKey = 'textContent' in document.createElement('div') ? 'textContent' : 'innerText'; } return contentKey;
}
module.exports = getTextContentAccessor;
},{“./ExecutionEnvironment”:21}],122:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule getUnboundedScrollPosition * @typechecks */
“use strict”;
/**
* Gets the scroll position of the supplied element or window. * * The return values are unbounded, unlike `getScrollPosition`. This means they * may be negative or exceed the element boundaries (which is possible using * inertial scrolling). * * @param {DOMWindow|DOMElement} scrollable * @return {object} Map with `x` and `y` keys. */
function getUnboundedScrollPosition(scrollable) {
if (scrollable === window) { return { x: window.pageXOffset || document.documentElement.scrollLeft, y: window.pageYOffset || document.documentElement.scrollTop }; } return { x: scrollable.scrollLeft, y: scrollable.scrollTop };
}
module.exports = getUnboundedScrollPosition;
},{}],123:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule hyphenate * @typechecks */
var _uppercasePattern = /([A-Z])/g;
/**
* Hyphenates a camelcased string, for example: * * > hyphenate('backgroundColor') * < "background-color" * * @param {string} string * @return {string} */
function hyphenate(string) {
return string.replace(_uppercasePattern, '-$1').toLowerCase();
}
module.exports = hyphenate;
},{}],124:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule instantiateReactComponent * @typechecks static-only */
“use strict”;
var warning = dereq(“./warning”);
/**
* Validate a `componentDescriptor`. This should be exposed publicly in a follow * up diff. * * @param {object} descriptor * @return {boolean} Returns true if this is a valid descriptor of a Component. */
function isValidComponentDescriptor(descriptor) {
return ( typeof descriptor.constructor === 'function' && typeof descriptor.constructor.prototype.construct === 'function' && typeof descriptor.constructor.prototype.mountComponent === 'function' && typeof descriptor.constructor.prototype.receiveComponent === 'function' );
}
/**
* Given a `componentDescriptor` create an instance that will actually be * mounted. Currently it just extracts an existing clone from composite * components but this is an implementation detail which will change. * * @param {object} descriptor * @return {object} A new instance of componentDescriptor's constructor. * @protected */
function instantiateReactComponent(descriptor) {
if ("production" !== "development") { ("production" !== "development" ? warning( isValidComponentDescriptor(descriptor), 'Only React Components are valid for mounting.' ) : null); // We use the clone of a composite component instead of the original // instance. This allows us to warn you if you're are accessing the wrong // instance. var instance = descriptor.__realComponentInstance || descriptor; instance._descriptor = descriptor; return instance; } // In prod we don't clone, we simply use the same instance for unaffected // behavior. We have to keep the descriptor around for comparison later on. // This should ideally be accepted in the constructor of the instance but // since that is currently overloaded, we just manually attach it here. descriptor._descriptor = descriptor; return descriptor;
}
module.exports = instantiateReactComponent;
},{“./warning”:148}],125:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule invariant */
“use strict”;
/**
* Use invariant() to assert state which your program assumes to be true. * * Provide sprintf-style format (only %s is supported) and arguments * to provide information about what broke and what you were * expecting. * * The invariant message will be stripped in production, but the invariant * will remain to ensure logic does not differ in production. */
var invariant = function(condition) {
if (!condition) { var error = new Error( 'Minified exception occured; use the non-minified dev environment for ' + 'the full error message and additional helpful warnings.' ); error.framesToPop = 1; throw error; }
};
if (“production” !== “development”) {
invariant = function(condition, format, a, b, c, d, e, f) { if (format === undefined) { throw new Error('invariant requires an error message argument'); } if (!condition) { var args = [a, b, c, d, e, f]; var argIndex = 0; var error = new Error( 'Invariant Violation: ' + format.replace(/%s/g, function() { return args[argIndex++]; }) ); error.framesToPop = 1; // we don't care about invariant's own frame throw error; } };
}
module.exports = invariant;
},{}],126:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule isEventSupported */
“use strict”;
var ExecutionEnvironment = dereq(“./ExecutionEnvironment”);
var useHasFeature; if (ExecutionEnvironment.canUseDOM) {
useHasFeature = document.implementation && document.implementation.hasFeature && // always returns true in newer browsers as per the standard. // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature document.implementation.hasFeature('', '') !== true;
}
/**
* Checks if an event is supported in the current execution environment. * * NOTE: This will not work correctly for non-generic events such as `change`, * `reset`, `load`, `error`, and `select`. * * Borrows from Modernizr. * * @param {string} eventNameSuffix Event name, e.g. "click". * @param {?boolean} capture Check if the capture phase is supported. * @return {boolean} True if the event is supported. * @internal * @license Modernizr 3.0.0pre (Custom Build) | MIT */
function isEventSupported(eventNameSuffix, capture) {
if (!ExecutionEnvironment.canUseDOM || capture && !('addEventListener' in document)) { return false; } var eventName = 'on' + eventNameSuffix; var isSupported = eventName in document; if (!isSupported) { var element = document.createElement('div'); element.setAttribute(eventName, 'return;'); isSupported = typeof element[eventName] === 'function'; } if (!isSupported && useHasFeature && eventNameSuffix === 'wheel') { // This is the only way to test support for the `wheel` event in IE9+. isSupported = document.implementation.hasFeature('Events.wheel', '3.0'); } return isSupported;
}
module.exports = isEventSupported;
},{“./ExecutionEnvironment”:21}],127:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule isNode * @typechecks */
/**
* @param {*} object The object to check. * @return {boolean} Whether or not the object is a DOM node. */
function isNode(object) {
return !!(object && ( typeof Node === 'function' ? object instanceof Node : typeof object === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string' ));
}
module.exports = isNode;
},{}],128:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule isTextInputElement */
“use strict”;
/**
* @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary */
var supportedInputTypes = {
'color': true, 'date': true, 'datetime': true, 'datetime-local': true, 'email': true, 'month': true, 'number': true, 'password': true, 'range': true, 'search': true, 'tel': true, 'text': true, 'time': true, 'url': true, 'week': true
};
function isTextInputElement(elem) {
return elem && ( (elem.nodeName === 'INPUT' && supportedInputTypes[elem.type]) || elem.nodeName === 'TEXTAREA' );
}
module.exports = isTextInputElement;
},{}],129:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule isTextNode * @typechecks */
var isNode = dereq(“./isNode”);
/**
* @param {*} object The object to check. * @return {boolean} Whether or not the object is a DOM text node. */
function isTextNode(object) {
return isNode(object) && object.nodeType == 3;
}
module.exports = isTextNode;
},{“./isNode”:127}],130:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule joinClasses * @typechecks static-only */
“use strict”;
/**
* Combines multiple className strings into one. * http://jsperf.com/joinclasses-args-vs-array * * @param {...?string} classes * @return {string} */
function joinClasses(className/*, … */) {
if (!className) { className = ''; } var nextClass; var argLength = arguments.length; if (argLength > 1) { for (var ii = 1; ii < argLength; ii++) { nextClass = arguments[ii]; nextClass && (className += ' ' + nextClass); } } return className;
}
module.exports = joinClasses;
},{}],131:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule keyMirror * @typechecks static-only */
“use strict”;
var invariant = dereq(“./invariant”);
/**
* Constructs an enumeration with keys equal to their value. * * For example: * * var COLORS = keyMirror({blue: null, red: null}); * var myColor = COLORS.blue; * var isColorValid = !!COLORS[myColor]; * * The last line could not be performed if the values of the generated enum were * not equal to their keys. * * Input: {key1: val1, key2: val2} * Output: {key1: key1, key2: key2} * * @param {object} obj * @return {object} */
var keyMirror = function(obj) {
var ret = {}; var key; ("production" !== "development" ? invariant( obj instanceof Object && !Array.isArray(obj), 'keyMirror(...): Argument must be an object.' ) : invariant(obj instanceof Object && !Array.isArray(obj))); for (key in obj) { if (!obj.hasOwnProperty(key)) { continue; } ret[key] = key; } return ret;
};
module.exports = keyMirror;
},{“./invariant”:125}],132:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule keyOf */
/**
* Allows extraction of a minified key. Let's the build system minify keys * without loosing the ability to dynamically use key strings as values * themselves. Pass in an object with a single key/val pair and it will return * you the string key of that single record. Suppose you want to grab the * value for a key 'className' inside of an object. Key/val minification may * have aliased that key to be 'xa12'. keyOf({className: null}) will return * 'xa12' in that case. Resolve keys you want to use once at startup time, then * reuse those resolutions. */
var keyOf = function(oneKeyObj) {
var key; for (key in oneKeyObj) { if (!oneKeyObj.hasOwnProperty(key)) { continue; } return key; } return null;
};
module.exports = keyOf;
},{}],133:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule memoizeStringOnly * @typechecks static-only */
“use strict”;
/**
* Memoizes the return value of a function that accepts one string argument. * * @param {function} callback * @return {function} */
function memoizeStringOnly(callback) {
var cache = {}; return function(string) { if (cache.hasOwnProperty(string)) { return cache[string]; } else { return cache[string] = callback.call(this, string); } };
}
module.exports = memoizeStringOnly;
},{}],134:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule merge */
“use strict”;
var mergeInto = dereq(“./mergeInto”);
/**
* Shallow merges two structures into a return value, without mutating either. * * @param {?object} one Optional object with properties to merge from. * @param {?object} two Optional object with properties to merge from. * @return {object} The shallow extension of one by two. */
var merge = function(one, two) {
var result = {}; mergeInto(result, one); mergeInto(result, two); return result;
};
module.exports = merge;
},{“./mergeInto”:136}],135:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule mergeHelpers * * requiresPolyfills: Array.isArray */
“use strict”;
var invariant = dereq(“./invariant”); var keyMirror = dereq(“./keyMirror”);
/**
* Maximum number of levels to traverse. Will catch circular structures. * @const */
var MAX_MERGE_DEPTH = 36;
/**
* We won't worry about edge cases like new String('x') or new Boolean(true). * Functions are considered terminals, and arrays are not. * @param {*} o The item/object/value to test. * @return {boolean} true iff the argument is a terminal. */
var isTerminal = function(o) {
return typeof o !== 'object' || o === null;
};
var mergeHelpers = {
MAX_MERGE_DEPTH: MAX_MERGE_DEPTH, isTerminal: isTerminal, /** * Converts null/undefined values into empty object. * * @param {?Object=} arg Argument to be normalized (nullable optional) * @return {!Object} */ normalizeMergeArg: function(arg) { return arg === undefined || arg === null ? {} : arg; }, /** * If merging Arrays, a merge strategy *must* be supplied. If not, it is * likely the caller's fault. If this function is ever called with anything * but `one` and `two` being `Array`s, it is the fault of the merge utilities. * * @param {*} one Array to merge into. * @param {*} two Array to merge from. */ checkMergeArrayArgs: function(one, two) { ("production" !== "development" ? invariant( Array.isArray(one) && Array.isArray(two), 'Tried to merge arrays, instead got %s and %s.', one, two ) : invariant(Array.isArray(one) && Array.isArray(two))); }, /** * @param {*} one Object to merge into. * @param {*} two Object to merge from. */ checkMergeObjectArgs: function(one, two) { mergeHelpers.checkMergeObjectArg(one); mergeHelpers.checkMergeObjectArg(two); }, /** * @param {*} arg */ checkMergeObjectArg: function(arg) { ("production" !== "development" ? invariant( !isTerminal(arg) && !Array.isArray(arg), 'Tried to merge an object, instead got %s.', arg ) : invariant(!isTerminal(arg) && !Array.isArray(arg))); }, /** * Checks that a merge was not given a circular object or an object that had * too great of depth. * * @param {number} Level of recursion to validate against maximum. */ checkMergeLevel: function(level) { ("production" !== "development" ? invariant( level < MAX_MERGE_DEPTH, 'Maximum deep merge depth exceeded. You may be attempting to merge ' + 'circular structures in an unsupported way.' ) : invariant(level < MAX_MERGE_DEPTH)); }, /** * Checks that the supplied merge strategy is valid. * * @param {string} Array merge strategy. */ checkArrayStrategy: function(strategy) { ("production" !== "development" ? invariant( strategy === undefined || strategy in mergeHelpers.ArrayStrategies, 'You must provide an array strategy to deep merge functions to ' + 'instruct the deep merge how to resolve merging two arrays.' ) : invariant(strategy === undefined || strategy in mergeHelpers.ArrayStrategies)); }, /** * Set of possible behaviors of merge algorithms when encountering two Arrays * that must be merged together. * - `clobber`: The left `Array` is ignored. * - `indexByIndex`: The result is achieved by recursively deep merging at * each index. (not yet supported.) */ ArrayStrategies: keyMirror({ Clobber: true, IndexByIndex: true })
};
module.exports = mergeHelpers;
},{“./invariant”:125,“./keyMirror”:131}],136:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule mergeInto * @typechecks static-only */
“use strict”;
var mergeHelpers = dereq(“./mergeHelpers”);
var checkMergeObjectArg = mergeHelpers.checkMergeObjectArg;
/**
* Shallow merges two structures by mutating the first parameter. * * @param {object} one Object to be merged into. * @param {?object} two Optional object with properties to merge from. */
function mergeInto(one, two) {
checkMergeObjectArg(one); if (two != null) { checkMergeObjectArg(two); for (var key in two) { if (!two.hasOwnProperty(key)) { continue; } one[key] = two[key]; } }
}
module.exports = mergeInto;
},{“./mergeHelpers”:135}],137:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule mixInto */
“use strict”;
/**
* Simply copies properties to the prototype. */
var mixInto = function(constructor, methodBag) {
var methodName; for (methodName in methodBag) { if (!methodBag.hasOwnProperty(methodName)) { continue; } constructor.prototype[methodName] = methodBag[methodName]; }
};
module.exports = mixInto;
},{}],138:[function(dereq,module,exports){ /**
* Copyright 2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule monitorCodeUse */
“use strict”;
var invariant = dereq(“./invariant”);
/**
* Provides open-source compatible instrumentation for monitoring certain API * uses before we're ready to issue a warning or refactor. It accepts an event * name which may only contain the characters [a-z0-9_] and an optional data * object with further information. */
function monitorCodeUse(eventName, data) {
("production" !== "development" ? invariant( eventName && !/[^a-z0-9_]/.test(eventName), 'You must provide an eventName using only the characters [a-z0-9_]' ) : invariant(eventName && !/[^a-z0-9_]/.test(eventName)));
}
module.exports = monitorCodeUse;
},{“./invariant”:125}],139:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule objMap */
“use strict”;
/**
* For each key/value pair, invokes callback func and constructs a resulting * object which contains, for every key in obj, values that are the result of * of invoking the function: * * func(value, key, iteration) * * @param {?object} obj Object to map keys over * @param {function} func Invoked for each key/val pair. * @param {?*} context * @return {?object} Result of mapping or null if obj is falsey */
function objMap(obj, func, context) {
if (!obj) { return null; } var i = 0; var ret = {}; for (var key in obj) { if (obj.hasOwnProperty(key)) { ret[key] = func.call(context, obj[key], key, i++); } } return ret;
}
module.exports = objMap;
},{}],140:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule objMapKeyVal */
“use strict”;
/**
* Behaves the same as `objMap` but invokes func with the key first, and value * second. Use `objMap` unless you need this special case. * Invokes func as: * * func(key, value, iteration) * * @param {?object} obj Object to map keys over * @param {!function} func Invoked for each key/val pair. * @param {?*} context * @return {?object} Result of mapping or null if obj is falsey */
function objMapKeyVal(obj, func, context) {
if (!obj) { return null; } var i = 0; var ret = {}; for (var key in obj) { if (obj.hasOwnProperty(key)) { ret[key] = func.call(context, key, obj[key], i++); } } return ret;
}
module.exports = objMapKeyVal;
},{}],141:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule onlyChild */
“use strict”;
var ReactComponent = dereq(“./ReactComponent”);
var invariant = dereq(“./invariant”);
/**
* Returns the first child in a collection of children and verifies that there * is only one child in the collection. The current implementation of this * function assumes that a single child gets passed without a wrapper, but the * purpose of this helper function is to abstract away the particular structure * of children. * * @param {?object} children Child collection structure. * @return {ReactComponent} The first and only `ReactComponent` contained in the * structure. */
function onlyChild(children) {
("production" !== "development" ? invariant( ReactComponent.isValidComponent(children), 'onlyChild must be passed a children with exactly one child.' ) : invariant(ReactComponent.isValidComponent(children))); return children;
}
module.exports = onlyChild;
},{“./ReactComponent”:31,“./invariant”:125}],142:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule performanceNow * @typechecks static-only */
“use strict”;
var ExecutionEnvironment = dereq(“./ExecutionEnvironment”);
/**
* Detect if we can use window.performance.now() and gracefully * fallback to Date.now() if it doesn't exist. * We need to support Firefox < 15 for now due to Facebook's webdriver * infrastructure. */
var performance = null;
if (ExecutionEnvironment.canUseDOM) {
performance = window.performance || window.webkitPerformance;
}
if (!performance || !performance.now) {
performance = Date;
}
var performanceNow = performance.now.bind(performance);
module.exports = performanceNow;
},{“./ExecutionEnvironment”:21}],143:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule shallowEqual */
“use strict”;
/**
* Performs equality by iterating through keys on an object and returning * false when any key has values which are not strictly equal between * objA and objB. Returns true when the values of all keys are strictly equal. * * @return {boolean} */
function shallowEqual(objA, objB) {
if (objA === objB) { return true; } var key; // Test for A's keys different from B. for (key in objA) { if (objA.hasOwnProperty(key) && (!objB.hasOwnProperty(key) || objA[key] !== objB[key])) { return false; } } // Test for B'a keys missing from A. for (key in objB) { if (objB.hasOwnProperty(key) && !objA.hasOwnProperty(key)) { return false; } } return true;
}
module.exports = shallowEqual;
},{}],144:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule shouldUpdateReactComponent * @typechecks static-only */
“use strict”;
/**
* Given a `prevComponentInstance` and `nextComponent`, determines if * `prevComponentInstance` should be updated as opposed to being destroyed or * replaced by a new instance. The second argument is a descriptor. Future * versions of the reconciler should only compare descriptors to other * descriptors. * * @param {?object} prevComponentInstance * @param {?object} nextDescriptor * @return {boolean} True if `prevComponentInstance` should be updated. * @protected */
function shouldUpdateReactComponent(prevComponentInstance, nextDescriptor) {
// TODO: Remove warning after a release. if (prevComponentInstance && nextDescriptor && prevComponentInstance.constructor === nextDescriptor.constructor && ( (prevComponentInstance.props && prevComponentInstance.props.key) === (nextDescriptor.props && nextDescriptor.props.key) )) { if (prevComponentInstance._owner === nextDescriptor._owner) { return true; } else { if ("production" !== "development") { if (prevComponentInstance.state) { console.warn( 'A recent change to React has been found to impact your code. ' + 'A mounted component will now be unmounted and replaced by a ' + 'component (of the same class) if their owners are different. ' + 'Previously, ownership was not considered when updating.', prevComponentInstance, nextDescriptor ); } } } } return false;
}
module.exports = shouldUpdateReactComponent;
},{}],145:[function(dereq,module,exports){ /**
* Copyright 2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule toArray * @typechecks */
var invariant = dereq(“./invariant”);
/**
* Convert array-like objects to arrays. * * This API assumes the caller knows the contents of the data type. For less * well defined inputs use createArrayFrom. * * @param {object|function} obj * @return {array} */
function toArray(obj) {
var length = obj.length; // Some browse builtin objects can report typeof 'function' (e.g. NodeList in // old versions of Safari). ("production" !== "development" ? invariant( !Array.isArray(obj) && (typeof obj === 'object' || typeof obj === 'function'), 'toArray: Array-like object expected' ) : invariant(!Array.isArray(obj) && (typeof obj === 'object' || typeof obj === 'function'))); ("production" !== "development" ? invariant( typeof length === 'number', 'toArray: Object needs a length property' ) : invariant(typeof length === 'number')); ("production" !== "development" ? invariant( length === 0 || (length - 1) in obj, 'toArray: Object should have keys for indices' ) : invariant(length === 0 || (length - 1) in obj)); // Old IE doesn't give collections access to hasOwnProperty. Assume inputs // without method will throw during the slice call and skip straight to the // fallback. if (obj.hasOwnProperty) { try { return Array.prototype.slice.call(obj); } catch (e) { // IE < 9 does not support Array#slice on collections objects } } // Fall back to copying key by key. This assumes all keys have a value, // so will not preserve sparsely populated inputs. var ret = Array(length); for (var ii = 0; ii < length; ii++) { ret[ii] = obj[ii]; } return ret;
}
module.exports = toArray;
},{“./invariant”:125}],146:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule traverseAllChildren */
“use strict”;
var ReactInstanceHandles = dereq(“./ReactInstanceHandles”); var ReactTextComponent = dereq(“./ReactTextComponent”);
var invariant = dereq(“./invariant”);
var SEPARATOR = ReactInstanceHandles.SEPARATOR; var SUBSEPARATOR = ':';
/**
* TODO: Test that: * 1. `mapChildren` transforms strings and numbers into `ReactTextComponent`. * 2. it('should fail when supplied duplicate key', function() { * 3. That a single child and an array with one item have the same key pattern. * }); */
var userProvidedKeyEscaperLookup = {
'=': '=0', '.': '=1', ':': '=2'
};
var userProvidedKeyEscapeRegex = /[=.:]/g;
function userProvidedKeyEscaper(match) {
return userProvidedKeyEscaperLookup[match];
}
/**
* Generate a key string that identifies a component within a set. * * @param {*} component A component that could contain a manual key. * @param {number} index Index that is used if a manual key is not provided. * @return {string} */
function getComponentKey(component, index) {
if (component && component.props && component.props.key != null) { // Explicit key return wrapUserProvidedKey(component.props.key); } // Implicit key determined by the index in the set return index.toString(36);
}
/**
* Escape a component key so that it is safe to use in a reactid. * * @param {*} key Component key to be escaped. * @return {string} An escaped string. */
function escapeUserProvidedKey(text) {
return ('' + text).replace( userProvidedKeyEscapeRegex, userProvidedKeyEscaper );
}
/**
* Wrap a `key` value explicitly provided by the user to distinguish it from * implicitly-generated keys generated by a component's index in its parent. * * @param {string} key Value of a user-provided `key` attribute * @return {string} */
function wrapUserProvidedKey(key) {
return '$' + escapeUserProvidedKey(key);
}
/**
* @param {?*} children Children tree container. * @param {!string} nameSoFar Name of the key path so far. * @param {!number} indexSoFar Number of children encountered until this point. * @param {!function} callback Callback to invoke with each child found. * @param {?*} traverseContext Used to pass information throughout the traversal * process. * @return {!number} The number of children in this subtree. */
var traverseAllChildrenImpl =
function(children, nameSoFar, indexSoFar, callback, traverseContext) { var subtreeCount = 0; // Count of children found in the current subtree. if (Array.isArray(children)) { for (var i = 0; i < children.length; i++) { var child = children[i]; var nextName = ( nameSoFar + (nameSoFar ? SUBSEPARATOR : SEPARATOR) + getComponentKey(child, i) ); var nextIndex = indexSoFar + subtreeCount; subtreeCount += traverseAllChildrenImpl( child, nextName, nextIndex, callback, traverseContext ); } } else { var type = typeof children; var isOnlyChild = nameSoFar === ''; // If it's the only child, treat the name as if it was wrapped in an array // so that it's consistent if the number of children grows var storageName = isOnlyChild ? SEPARATOR + getComponentKey(children, 0) : nameSoFar; if (children == null || type === 'boolean') { // All of the above are perceived as null. callback(traverseContext, null, storageName, indexSoFar); subtreeCount = 1; } else if (children.type && children.type.prototype && children.type.prototype.mountComponentIntoNode) { callback(traverseContext, children, storageName, indexSoFar); subtreeCount = 1; } else { if (type === 'object') { ("production" !== "development" ? invariant( !children || children.nodeType !== 1, 'traverseAllChildren(...): Encountered an invalid child; DOM ' + 'elements are not valid children of React components.' ) : invariant(!children || children.nodeType !== 1)); for (var key in children) { if (children.hasOwnProperty(key)) { subtreeCount += traverseAllChildrenImpl( children[key], ( nameSoFar + (nameSoFar ? SUBSEPARATOR : SEPARATOR) + wrapUserProvidedKey(key) + SUBSEPARATOR + getComponentKey(children[key], 0) ), indexSoFar + subtreeCount, callback, traverseContext ); } } } else if (type === 'string') { var normalizedText = new ReactTextComponent(children); callback(traverseContext, normalizedText, storageName, indexSoFar); subtreeCount += 1; } else if (type === 'number') { var normalizedNumber = new ReactTextComponent('' + children); callback(traverseContext, normalizedNumber, storageName, indexSoFar); subtreeCount += 1; } } } return subtreeCount; };
/**
* Traverses children that are typically specified as `props.children`, but * might also be specified through attributes: * * - `traverseAllChildren(this.props.children, ...)` * - `traverseAllChildren(this.props.leftPanelChildren, ...)` * * The `traverseContext` is an optional argument that is passed through the * entire traversal. It can be used to store accumulations or anything else that * the callback might find relevant. * * @param {?*} children Children tree object. * @param {!function} callback To invoke upon traversing each child. * @param {?*} traverseContext Context for traversal. */
function traverseAllChildren(children, callback, traverseContext) {
if (children !== null && children !== undefined) { traverseAllChildrenImpl(children, '', 0, callback, traverseContext); }
}
module.exports = traverseAllChildren;
},{“./ReactInstanceHandles”:57,“./ReactTextComponent”:77,“./invariant”:125}],147:[function(dereq,module,exports){ /**
* Copyright 2013-2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule update */
“use strict”;
var copyProperties = dereq(“./copyProperties”); var keyOf = dereq(“./keyOf”); var invariant = dereq(“./invariant”);
function shallowCopy(x) {
if (Array.isArray(x)) { return x.concat(); } else if (x && typeof x === 'object') { return copyProperties(new x.constructor(), x); } else { return x; }
}
var DIRECTIVE_PUSH = keyOf({$push: null}); var DIRECTIVE_UNSHIFT = keyOf({$unshift: null}); var DIRECTIVE_SPLICE = keyOf({$splice: null}); var DIRECTIVE_SET = keyOf({$set: null}); var DIRECTIVE_MERGE = keyOf({$merge: null});
var ALL_DIRECTIVES_LIST = [
DIRECTIVE_PUSH, DIRECTIVE_UNSHIFT, DIRECTIVE_SPLICE, DIRECTIVE_SET, DIRECTIVE_MERGE
];
var ALL_DIRECTIVES_SET = {};
ALL_DIRECTIVES_LIST.forEach(function(directive) {
ALL_DIRECTIVES_SET[directive] = true;
});
function invariantArrayCase(value, spec, directive) {
("production" !== "development" ? invariant( Array.isArray(value), 'update(): expected target of %s to be an array; got %s.', directive, value ) : invariant(Array.isArray(value))); var specValue = spec[directive]; ("production" !== "development" ? invariant( Array.isArray(specValue), 'update(): expected spec of %s to be an array; got %s. ' + 'Did you forget to wrap your parameter in an array?', directive, specValue ) : invariant(Array.isArray(specValue)));
}
function update(value, spec) {
("production" !== "development" ? invariant( typeof spec === 'object', 'update(): You provided a key path to update() that did not contain one ' + 'of %s. Did you forget to include {%s: ...}?', ALL_DIRECTIVES_LIST.join(', '), DIRECTIVE_SET ) : invariant(typeof spec === 'object')); if (spec.hasOwnProperty(DIRECTIVE_SET)) { ("production" !== "development" ? invariant( Object.keys(spec).length === 1, 'Cannot have more than one key in an object with %s', DIRECTIVE_SET ) : invariant(Object.keys(spec).length === 1)); return spec[DIRECTIVE_SET]; } var nextValue = shallowCopy(value); if (spec.hasOwnProperty(DIRECTIVE_MERGE)) { var mergeObj = spec[DIRECTIVE_MERGE]; ("production" !== "development" ? invariant( mergeObj && typeof mergeObj === 'object', 'update(): %s expects a spec of type \'object\'; got %s', DIRECTIVE_MERGE, mergeObj ) : invariant(mergeObj && typeof mergeObj === 'object')); ("production" !== "development" ? invariant( nextValue && typeof nextValue === 'object', 'update(): %s expects a target of type \'object\'; got %s', DIRECTIVE_MERGE, nextValue ) : invariant(nextValue && typeof nextValue === 'object')); copyProperties(nextValue, spec[DIRECTIVE_MERGE]); } if (spec.hasOwnProperty(DIRECTIVE_PUSH)) { invariantArrayCase(value, spec, DIRECTIVE_PUSH); spec[DIRECTIVE_PUSH].forEach(function(item) { nextValue.push(item); }); } if (spec.hasOwnProperty(DIRECTIVE_UNSHIFT)) { invariantArrayCase(value, spec, DIRECTIVE_UNSHIFT); spec[DIRECTIVE_UNSHIFT].forEach(function(item) { nextValue.unshift(item); }); } if (spec.hasOwnProperty(DIRECTIVE_SPLICE)) { ("production" !== "development" ? invariant( Array.isArray(value), 'Expected %s target to be an array; got %s', DIRECTIVE_SPLICE, value ) : invariant(Array.isArray(value))); ("production" !== "development" ? invariant( Array.isArray(spec[DIRECTIVE_SPLICE]), 'update(): expected spec of %s to be an array of arrays; got %s. ' + 'Did you forget to wrap your parameters in an array?', DIRECTIVE_SPLICE, spec[DIRECTIVE_SPLICE] ) : invariant(Array.isArray(spec[DIRECTIVE_SPLICE]))); spec[DIRECTIVE_SPLICE].forEach(function(args) { ("production" !== "development" ? invariant( Array.isArray(args), 'update(): expected spec of %s to be an array of arrays; got %s. ' + 'Did you forget to wrap your parameters in an array?', DIRECTIVE_SPLICE, spec[DIRECTIVE_SPLICE] ) : invariant(Array.isArray(args))); nextValue.splice.apply(nextValue, args); }); } for (var k in spec) { if (!ALL_DIRECTIVES_SET[k]) { nextValue[k] = update(value[k], spec[k]); } } return nextValue;
}
module.exports = update;
},{“./copyProperties”:102,“./invariant”:125,“./keyOf”:132}],148:[function(dereq,module,exports){ /**
* Copyright 2014 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @providesModule warning */
“use strict”;
var emptyFunction = dereq(“./emptyFunction”);
/**
* Similar to invariant but only logs a warning if the condition is not met. * This can be used to log issues in development environments in critical * paths. Removing the logging code for production environments will keep the * same logic and follow the same code paths. */
var warning = emptyFunction;
if (“production” !== “development”) {
warning = function(condition, format ) {var args=Array.prototype.slice.call(arguments,2); if (format === undefined) { throw new Error( '`warning(condition, format, ...args)` requires a warning ' + 'message argument' ); } if (!condition) { var argIndex = 0; console.warn('Warning: ' + format.replace(/%s/g, function() {return args[argIndex++];})); } };
}
module.exports = warning;
},{“./emptyFunction”:109}]},{},[82]) (82) });