|
/** |
|
* ReactDOM v15.4.2 |
|
*/ |
|
|
|
;(function(f) { |
|
// CommonJS |
|
if (typeof exports === "object" && typeof module !== "undefined") { |
|
module.exports = f(require('react')); |
|
|
|
// RequireJS |
|
} else if (typeof define === "function" && define.amd) { |
|
define(['react'], f); |
|
|
|
// <script> |
|
} else { |
|
var g; |
|
if (typeof window !== "undefined") { |
|
g = window; |
|
} else if (typeof global !== "undefined") { |
|
g = global; |
|
} else if (typeof self !== "undefined") { |
|
g = self; |
|
} else { |
|
// works providing we're not in "use strict"; |
|
// needed for Java 8 Nashorn |
|
// see https://github.com/facebook/react/issues/3037 |
|
g = this; |
|
} |
|
g.ReactDOM = f(g.React); |
|
} |
|
})(function(React) { |
|
return (function(f){return f()})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var ARIADOMPropertyConfig = { |
|
Properties: { |
|
// Global States and Properties |
|
'aria-current': 0, // state |
|
'aria-details': 0, |
|
'aria-disabled': 0, // state |
|
'aria-hidden': 0, // state |
|
'aria-invalid': 0, // state |
|
'aria-keyshortcuts': 0, |
|
'aria-label': 0, |
|
'aria-roledescription': 0, |
|
// Widget Attributes |
|
'aria-autocomplete': 0, |
|
'aria-checked': 0, |
|
'aria-expanded': 0, |
|
'aria-haspopup': 0, |
|
'aria-level': 0, |
|
'aria-modal': 0, |
|
'aria-multiline': 0, |
|
'aria-multiselectable': 0, |
|
'aria-orientation': 0, |
|
'aria-placeholder': 0, |
|
'aria-pressed': 0, |
|
'aria-readonly': 0, |
|
'aria-required': 0, |
|
'aria-selected': 0, |
|
'aria-sort': 0, |
|
'aria-valuemax': 0, |
|
'aria-valuemin': 0, |
|
'aria-valuenow': 0, |
|
'aria-valuetext': 0, |
|
// Live Region Attributes |
|
'aria-atomic': 0, |
|
'aria-busy': 0, |
|
'aria-live': 0, |
|
'aria-relevant': 0, |
|
// Drag-and-Drop Attributes |
|
'aria-dropeffect': 0, |
|
'aria-grabbed': 0, |
|
// Relationship Attributes |
|
'aria-activedescendant': 0, |
|
'aria-colcount': 0, |
|
'aria-colindex': 0, |
|
'aria-colspan': 0, |
|
'aria-controls': 0, |
|
'aria-describedby': 0, |
|
'aria-errormessage': 0, |
|
'aria-flowto': 0, |
|
'aria-labelledby': 0, |
|
'aria-owns': 0, |
|
'aria-posinset': 0, |
|
'aria-rowcount': 0, |
|
'aria-rowindex': 0, |
|
'aria-rowspan': 0, |
|
'aria-setsize': 0 |
|
}, |
|
DOMAttributeNames: {}, |
|
DOMPropertyNames: {} |
|
}; |
|
|
|
module.exports = ARIADOMPropertyConfig; |
|
},{}],2:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var ReactDOMComponentTree = _dereq_(34); |
|
|
|
var focusNode = _dereq_(144); |
|
|
|
var AutoFocusUtils = { |
|
focusDOMComponent: function () { |
|
focusNode(ReactDOMComponentTree.getNodeFromInstance(this)); |
|
} |
|
}; |
|
|
|
module.exports = AutoFocusUtils; |
|
},{"144":144,"34":34}],3:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var EventPropagators = _dereq_(20); |
|
var ExecutionEnvironment = _dereq_(136); |
|
var FallbackCompositionState = _dereq_(21); |
|
var SyntheticCompositionEvent = _dereq_(89); |
|
var SyntheticInputEvent = _dereq_(93); |
|
|
|
var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space |
|
var START_KEYCODE = 229; |
|
|
|
var canUseCompositionEvent = ExecutionEnvironment.canUseDOM && 'CompositionEvent' in window; |
|
|
|
var documentMode = null; |
|
if (ExecutionEnvironment.canUseDOM && 'documentMode' in document) { |
|
documentMode = document.documentMode; |
|
} |
|
|
|
// Webkit offers a very useful `textInput` event that can be used to |
|
// directly represent `beforeInput`. The IE `textinput` event is not as |
|
// useful, so we don't use it. |
|
var canUseTextInputEvent = ExecutionEnvironment.canUseDOM && 'TextEvent' in window && !documentMode && !isPresto(); |
|
|
|
// In IE9+, we have access to composition events, but the data supplied |
|
// by the native compositionend event may be incorrect. Japanese ideographic |
|
// spaces, for instance (\u3000) are not recorded correctly. |
|
var useFallbackCompositionData = ExecutionEnvironment.canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11); |
|
|
|
/** |
|
* Opera <= 12 includes TextEvent in window, but does not fire |
|
* text input events. Rely on keypress instead. |
|
*/ |
|
function isPresto() { |
|
var opera = window.opera; |
|
return typeof opera === 'object' && typeof opera.version === 'function' && parseInt(opera.version(), 10) <= 12; |
|
} |
|
|
|
var SPACEBAR_CODE = 32; |
|
var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE); |
|
|
|
// Events and their corresponding property names. |
|
var eventTypes = { |
|
beforeInput: { |
|
phasedRegistrationNames: { |
|
bubbled: 'onBeforeInput', |
|
captured: 'onBeforeInputCapture' |
|
}, |
|
dependencies: ['topCompositionEnd', 'topKeyPress', 'topTextInput', 'topPaste'] |
|
}, |
|
compositionEnd: { |
|
phasedRegistrationNames: { |
|
bubbled: 'onCompositionEnd', |
|
captured: 'onCompositionEndCapture' |
|
}, |
|
dependencies: ['topBlur', 'topCompositionEnd', 'topKeyDown', 'topKeyPress', 'topKeyUp', 'topMouseDown'] |
|
}, |
|
compositionStart: { |
|
phasedRegistrationNames: { |
|
bubbled: 'onCompositionStart', |
|
captured: 'onCompositionStartCapture' |
|
}, |
|
dependencies: ['topBlur', 'topCompositionStart', 'topKeyDown', 'topKeyPress', 'topKeyUp', 'topMouseDown'] |
|
}, |
|
compositionUpdate: { |
|
phasedRegistrationNames: { |
|
bubbled: 'onCompositionUpdate', |
|
captured: 'onCompositionUpdateCapture' |
|
}, |
|
dependencies: ['topBlur', 'topCompositionUpdate', 'topKeyDown', 'topKeyPress', 'topKeyUp', 'topMouseDown'] |
|
} |
|
}; |
|
|
|
// Track whether we've ever handled a keypress on the space key. |
|
var hasSpaceKeypress = false; |
|
|
|
/** |
|
* Return whether a native keypress event is assumed to be a command. |
|
* This is required because Firefox fires `keypress` events for key commands |
|
* (cut, copy, select-all, etc.) even though no character is inserted. |
|
*/ |
|
function isKeypressCommand(nativeEvent) { |
|
return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && |
|
// ctrlKey && altKey is equivalent to AltGr, and is not a command. |
|
!(nativeEvent.ctrlKey && nativeEvent.altKey); |
|
} |
|
|
|
/** |
|
* Translate native top level events into event types. |
|
* |
|
* @param {string} topLevelType |
|
* @return {object} |
|
*/ |
|
function getCompositionEventType(topLevelType) { |
|
switch (topLevelType) { |
|
case 'topCompositionStart': |
|
return eventTypes.compositionStart; |
|
case 'topCompositionEnd': |
|
return eventTypes.compositionEnd; |
|
case '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 isFallbackCompositionStart(topLevelType, nativeEvent) { |
|
return topLevelType === '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 isFallbackCompositionEnd(topLevelType, nativeEvent) { |
|
switch (topLevelType) { |
|
case 'topKeyUp': |
|
// Command keys insert or clear IME input. |
|
return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1; |
|
case 'topKeyDown': |
|
// Expect IME keyCode on each keydown. If we get any other |
|
// code we must have exited earlier. |
|
return nativeEvent.keyCode !== START_KEYCODE; |
|
case 'topKeyPress': |
|
case 'topMouseDown': |
|
case 'topBlur': |
|
// Events are not possible without cancelling IME. |
|
return true; |
|
default: |
|
return false; |
|
} |
|
} |
|
|
|
/** |
|
* Google Input Tools provides composition data via a CustomEvent, |
|
* with the `data` property populated in the `detail` object. If this |
|
* is available on the event object, use it. If not, this is a plain |
|
* composition event and we have nothing special to extract. |
|
* |
|
* @param {object} nativeEvent |
|
* @return {?string} |
|
*/ |
|
function getDataFromCustomEvent(nativeEvent) { |
|
var detail = nativeEvent.detail; |
|
if (typeof detail === 'object' && 'data' in detail) { |
|
return detail.data; |
|
} |
|
return null; |
|
} |
|
|
|
// Track the current IME composition fallback object, if any. |
|
var currentComposition = null; |
|
|
|
/** |
|
* @return {?object} A SyntheticCompositionEvent. |
|
*/ |
|
function extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) { |
|
var eventType; |
|
var fallbackData; |
|
|
|
if (canUseCompositionEvent) { |
|
eventType = getCompositionEventType(topLevelType); |
|
} else if (!currentComposition) { |
|
if (isFallbackCompositionStart(topLevelType, nativeEvent)) { |
|
eventType = eventTypes.compositionStart; |
|
} |
|
} else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) { |
|
eventType = eventTypes.compositionEnd; |
|
} |
|
|
|
if (!eventType) { |
|
return null; |
|
} |
|
|
|
if (useFallbackCompositionData) { |
|
// The current composition is stored statically and must not be |
|
// overwritten while composition continues. |
|
if (!currentComposition && eventType === eventTypes.compositionStart) { |
|
currentComposition = FallbackCompositionState.getPooled(nativeEventTarget); |
|
} else if (eventType === eventTypes.compositionEnd) { |
|
if (currentComposition) { |
|
fallbackData = currentComposition.getData(); |
|
} |
|
} |
|
} |
|
|
|
var event = SyntheticCompositionEvent.getPooled(eventType, targetInst, nativeEvent, nativeEventTarget); |
|
|
|
if (fallbackData) { |
|
// Inject data generated from fallback path into the synthetic event. |
|
// This matches the property of native CompositionEventInterface. |
|
event.data = fallbackData; |
|
} else { |
|
var customData = getDataFromCustomEvent(nativeEvent); |
|
if (customData !== null) { |
|
event.data = customData; |
|
} |
|
} |
|
|
|
EventPropagators.accumulateTwoPhaseDispatches(event); |
|
return event; |
|
} |
|
|
|
/** |
|
* @param {string} topLevelType Record from `EventConstants`. |
|
* @param {object} nativeEvent Native browser event. |
|
* @return {?string} The string corresponding to this `beforeInput` event. |
|
*/ |
|
function getNativeBeforeInputChars(topLevelType, nativeEvent) { |
|
switch (topLevelType) { |
|
case 'topCompositionEnd': |
|
return getDataFromCustomEvent(nativeEvent); |
|
case 'topKeyPress': |
|
/** |
|
* If native `textInput` events are available, our goal is to make |
|
* use of them. However, there is a special case: the spacebar key. |
|
* In Webkit, preventing default on a spacebar `textInput` event |
|
* cancels character insertion, but it *also* causes the browser |
|
* to fall back to its default spacebar behavior of scrolling the |
|
* page. |
|
* |
|
* Tracking at: |
|
* https://code.google.com/p/chromium/issues/detail?id=355103 |
|
* |
|
* To avoid this issue, use the keypress event as if no `textInput` |
|
* event is available. |
|
*/ |
|
var which = nativeEvent.which; |
|
if (which !== SPACEBAR_CODE) { |
|
return null; |
|
} |
|
|
|
hasSpaceKeypress = true; |
|
return SPACEBAR_CHAR; |
|
|
|
case 'topTextInput': |
|
// Record the characters to be added to the DOM. |
|
var chars = nativeEvent.data; |
|
|
|
// If it's a spacebar character, assume that we have already handled |
|
// it at the keypress level and bail immediately. Android Chrome |
|
// doesn't give us keycodes, so we need to blacklist it. |
|
if (chars === SPACEBAR_CHAR && hasSpaceKeypress) { |
|
return null; |
|
} |
|
|
|
return chars; |
|
|
|
default: |
|
// For other native event types, do nothing. |
|
return null; |
|
} |
|
} |
|
|
|
/** |
|
* For browsers that do not provide the `textInput` event, extract the |
|
* appropriate string to use for SyntheticInputEvent. |
|
* |
|
* @param {string} topLevelType Record from `EventConstants`. |
|
* @param {object} nativeEvent Native browser event. |
|
* @return {?string} The fallback string for this `beforeInput` event. |
|
*/ |
|
function getFallbackBeforeInputChars(topLevelType, nativeEvent) { |
|
// If we are currently composing (IME) and using a fallback to do so, |
|
// try to extract the composed characters from the fallback object. |
|
// If composition event is available, we extract a string only at |
|
// compositionevent, otherwise extract it at fallback events. |
|
if (currentComposition) { |
|
if (topLevelType === 'topCompositionEnd' || !canUseCompositionEvent && isFallbackCompositionEnd(topLevelType, nativeEvent)) { |
|
var chars = currentComposition.getData(); |
|
FallbackCompositionState.release(currentComposition); |
|
currentComposition = null; |
|
return chars; |
|
} |
|
return null; |
|
} |
|
|
|
switch (topLevelType) { |
|
case 'topPaste': |
|
// If a paste event occurs after a keypress, throw out the input |
|
// chars. Paste events should not lead to BeforeInput events. |
|
return null; |
|
case 'topKeyPress': |
|
/** |
|
* As of v27, Firefox may fire keypress events even when no character |
|
* will be inserted. A few possibilities: |
|
* |
|
* - `which` is `0`. Arrow keys, Esc key, etc. |
|
* |
|
* - `which` is the pressed key code, but no char is available. |
|
* Ex: 'AltGr + d` in Polish. There is no modified character for |
|
* this key combination and no character is inserted into the |
|
* document, but FF fires the keypress for char code `100` anyway. |
|
* No `input` event will occur. |
|
* |
|
* - `which` is the pressed key code, but a command combination is |
|
* being used. Ex: `Cmd+C`. No character is inserted, and no |
|
* `input` event will occur. |
|
*/ |
|
if (nativeEvent.which && !isKeypressCommand(nativeEvent)) { |
|
return String.fromCharCode(nativeEvent.which); |
|
} |
|
return null; |
|
case 'topCompositionEnd': |
|
return useFallbackCompositionData ? null : nativeEvent.data; |
|
default: |
|
return null; |
|
} |
|
} |
|
|
|
/** |
|
* Extract a SyntheticInputEvent for `beforeInput`, based on either native |
|
* `textInput` or fallback behavior. |
|
* |
|
* @return {?object} A SyntheticInputEvent. |
|
*/ |
|
function extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) { |
|
var chars; |
|
|
|
if (canUseTextInputEvent) { |
|
chars = getNativeBeforeInputChars(topLevelType, nativeEvent); |
|
} else { |
|
chars = getFallbackBeforeInputChars(topLevelType, nativeEvent); |
|
} |
|
|
|
// If no characters are being inserted, no BeforeInput event should |
|
// be fired. |
|
if (!chars) { |
|
return null; |
|
} |
|
|
|
var event = SyntheticInputEvent.getPooled(eventTypes.beforeInput, targetInst, nativeEvent, nativeEventTarget); |
|
|
|
event.data = chars; |
|
EventPropagators.accumulateTwoPhaseDispatches(event); |
|
return event; |
|
} |
|
|
|
/** |
|
* Create an `onBeforeInput` event to match |
|
* http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents. |
|
* |
|
* This event plugin is based on the native `textInput` event |
|
* available in Chrome, Safari, Opera, and IE. This event fires after |
|
* `onKeyPress` and `onCompositionEnd`, but before `onInput`. |
|
* |
|
* `beforeInput` is spec'd but not implemented in any browsers, and |
|
* the `input` event does not provide any useful information about what has |
|
* actually been added, contrary to the spec. Thus, `textInput` is the best |
|
* available event to identify the characters that have actually been inserted |
|
* into the target node. |
|
* |
|
* This plugin is also responsible for emitting `composition` events, thus |
|
* allowing us to share composition fallback code for both `beforeInput` and |
|
* `composition` event types. |
|
*/ |
|
var BeforeInputEventPlugin = { |
|
|
|
eventTypes: eventTypes, |
|
|
|
extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { |
|
return [extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget), extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget)]; |
|
} |
|
}; |
|
|
|
module.exports = BeforeInputEventPlugin; |
|
},{"136":136,"20":20,"21":21,"89":89,"93":93}],4:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
/** |
|
* CSS properties which accept numbers but are not in units of "px". |
|
*/ |
|
|
|
var isUnitlessNumber = { |
|
animationIterationCount: true, |
|
borderImageOutset: true, |
|
borderImageSlice: true, |
|
borderImageWidth: true, |
|
boxFlex: true, |
|
boxFlexGroup: true, |
|
boxOrdinalGroup: true, |
|
columnCount: true, |
|
flex: true, |
|
flexGrow: true, |
|
flexPositive: true, |
|
flexShrink: true, |
|
flexNegative: true, |
|
flexOrder: true, |
|
gridRow: true, |
|
gridColumn: true, |
|
fontWeight: true, |
|
lineClamp: true, |
|
lineHeight: true, |
|
opacity: true, |
|
order: true, |
|
orphans: true, |
|
tabSize: true, |
|
widows: true, |
|
zIndex: true, |
|
zoom: true, |
|
|
|
// SVG-related properties |
|
fillOpacity: true, |
|
floodOpacity: true, |
|
stopOpacity: true, |
|
strokeDasharray: true, |
|
strokeDashoffset: true, |
|
strokeMiterlimit: true, |
|
strokeOpacity: true, |
|
strokeWidth: 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: { |
|
backgroundAttachment: true, |
|
backgroundColor: true, |
|
backgroundImage: true, |
|
backgroundPositionX: true, |
|
backgroundPositionY: true, |
|
backgroundRepeat: true |
|
}, |
|
backgroundPosition: { |
|
backgroundPositionX: true, |
|
backgroundPositionY: 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 |
|
}, |
|
outline: { |
|
outlineWidth: true, |
|
outlineStyle: true, |
|
outlineColor: true |
|
} |
|
}; |
|
|
|
var CSSProperty = { |
|
isUnitlessNumber: isUnitlessNumber, |
|
shorthandPropertyExpansions: shorthandPropertyExpansions |
|
}; |
|
|
|
module.exports = CSSProperty; |
|
},{}],5:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var CSSProperty = _dereq_(4); |
|
var ExecutionEnvironment = _dereq_(136); |
|
var ReactInstrumentation = _dereq_(64); |
|
|
|
var camelizeStyleName = _dereq_(138); |
|
var dangerousStyleValue = _dereq_(106); |
|
var hyphenateStyleName = _dereq_(149); |
|
var memoizeStringOnly = _dereq_(153); |
|
var warning = _dereq_(157); |
|
|
|
var processStyleName = memoizeStringOnly(function (styleName) { |
|
return hyphenateStyleName(styleName); |
|
}); |
|
|
|
var hasShorthandPropertyBug = false; |
|
var styleFloatAccessor = 'cssFloat'; |
|
if (ExecutionEnvironment.canUseDOM) { |
|
var tempStyle = document.createElement('div').style; |
|
try { |
|
// IE8 throws "Invalid argument." if resetting shorthand style properties. |
|
tempStyle.font = ''; |
|
} catch (e) { |
|
hasShorthandPropertyBug = true; |
|
} |
|
// IE8 only supports accessing cssFloat (standard) as styleFloat |
|
if (document.documentElement.style.cssFloat === undefined) { |
|
styleFloatAccessor = 'styleFloat'; |
|
} |
|
} |
|
|
|
if ("development" !== 'production') { |
|
// 'msTransform' is correct, but the other prefixes should be capitalized |
|
var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/; |
|
|
|
// style values shouldn't contain a semicolon |
|
var badStyleValueWithSemicolonPattern = /;\s*$/; |
|
|
|
var warnedStyleNames = {}; |
|
var warnedStyleValues = {}; |
|
var warnedForNaNValue = false; |
|
|
|
var warnHyphenatedStyleName = function (name, owner) { |
|
if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { |
|
return; |
|
} |
|
|
|
warnedStyleNames[name] = true; |
|
"development" !== 'production' ? warning(false, 'Unsupported style property %s. Did you mean %s?%s', name, camelizeStyleName(name), checkRenderMessage(owner)) : void 0; |
|
}; |
|
|
|
var warnBadVendoredStyleName = function (name, owner) { |
|
if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { |
|
return; |
|
} |
|
|
|
warnedStyleNames[name] = true; |
|
"development" !== 'production' ? warning(false, 'Unsupported vendor-prefixed style property %s. Did you mean %s?%s', name, name.charAt(0).toUpperCase() + name.slice(1), checkRenderMessage(owner)) : void 0; |
|
}; |
|
|
|
var warnStyleValueWithSemicolon = function (name, value, owner) { |
|
if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) { |
|
return; |
|
} |
|
|
|
warnedStyleValues[value] = true; |
|
"development" !== 'production' ? warning(false, 'Style property values shouldn\'t contain a semicolon.%s ' + 'Try "%s: %s" instead.', checkRenderMessage(owner), name, value.replace(badStyleValueWithSemicolonPattern, '')) : void 0; |
|
}; |
|
|
|
var warnStyleValueIsNaN = function (name, value, owner) { |
|
if (warnedForNaNValue) { |
|
return; |
|
} |
|
|
|
warnedForNaNValue = true; |
|
"development" !== 'production' ? warning(false, '`NaN` is an invalid value for the `%s` css style property.%s', name, checkRenderMessage(owner)) : void 0; |
|
}; |
|
|
|
var checkRenderMessage = function (owner) { |
|
if (owner) { |
|
var name = owner.getName(); |
|
if (name) { |
|
return ' Check the render method of `' + name + '`.'; |
|
} |
|
} |
|
return ''; |
|
}; |
|
|
|
/** |
|
* @param {string} name |
|
* @param {*} value |
|
* @param {ReactDOMComponent} component |
|
*/ |
|
var warnValidStyle = function (name, value, component) { |
|
var owner; |
|
if (component) { |
|
owner = component._currentElement._owner; |
|
} |
|
if (name.indexOf('-') > -1) { |
|
warnHyphenatedStyleName(name, owner); |
|
} else if (badVendoredStyleNamePattern.test(name)) { |
|
warnBadVendoredStyleName(name, owner); |
|
} else if (badStyleValueWithSemicolonPattern.test(value)) { |
|
warnStyleValueWithSemicolon(name, value, owner); |
|
} |
|
|
|
if (typeof value === 'number' && isNaN(value)) { |
|
warnStyleValueIsNaN(name, value, owner); |
|
} |
|
}; |
|
} |
|
|
|
/** |
|
* Operations for dealing with CSS properties. |
|
*/ |
|
var CSSPropertyOperations = { |
|
|
|
/** |
|
* Serializes a mapping of style properties for use as inline styles: |
|
* |
|
* > createMarkupForStyles({width: '200px', height: 0}) |
|
* "width:200px;height:0;" |
|
* |
|
* Undefined values are ignored so that declarative programming is easier. |
|
* The result should be HTML-escaped before insertion into the DOM. |
|
* |
|
* @param {object} styles |
|
* @param {ReactDOMComponent} component |
|
* @return {?string} |
|
*/ |
|
createMarkupForStyles: function (styles, component) { |
|
var serialized = ''; |
|
for (var styleName in styles) { |
|
if (!styles.hasOwnProperty(styleName)) { |
|
continue; |
|
} |
|
var styleValue = styles[styleName]; |
|
if ("development" !== 'production') { |
|
warnValidStyle(styleName, styleValue, component); |
|
} |
|
if (styleValue != null) { |
|
serialized += processStyleName(styleName) + ':'; |
|
serialized += dangerousStyleValue(styleName, styleValue, component) + ';'; |
|
} |
|
} |
|
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 |
|
* @param {ReactDOMComponent} component |
|
*/ |
|
setValueForStyles: function (node, styles, component) { |
|
if ("development" !== 'production') { |
|
ReactInstrumentation.debugTool.onHostOperation({ |
|
instanceID: component._debugID, |
|
type: 'update styles', |
|
payload: styles |
|
}); |
|
} |
|
|
|
var style = node.style; |
|
for (var styleName in styles) { |
|
if (!styles.hasOwnProperty(styleName)) { |
|
continue; |
|
} |
|
if ("development" !== 'production') { |
|
warnValidStyle(styleName, styles[styleName], component); |
|
} |
|
var styleValue = dangerousStyleValue(styleName, styles[styleName], component); |
|
if (styleName === 'float' || styleName === 'cssFloat') { |
|
styleName = styleFloatAccessor; |
|
} |
|
if (styleValue) { |
|
style[styleName] = styleValue; |
|
} else { |
|
var expansion = hasShorthandPropertyBug && 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; |
|
},{"106":106,"136":136,"138":138,"149":149,"153":153,"157":157,"4":4,"64":64}],6:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125); |
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } |
|
|
|
var PooledClass = _dereq_(25); |
|
|
|
var invariant = _dereq_(150); |
|
|
|
/** |
|
* A specialized pseudo-event module to help keep track of components waiting to |
|
* be notified when their DOM representations are available for use. |
|
* |
|
* This implements `PooledClass`, so you should never need to instantiate this. |
|
* Instead, use `CallbackQueue.getPooled()`. |
|
* |
|
* @class ReactMountReady |
|
* @implements PooledClass |
|
* @internal |
|
*/ |
|
|
|
var CallbackQueue = function () { |
|
function CallbackQueue(arg) { |
|
_classCallCheck(this, CallbackQueue); |
|
|
|
this._callbacks = null; |
|
this._contexts = null; |
|
this._arg = arg; |
|
} |
|
|
|
/** |
|
* Enqueues a callback to be invoked when `notifyAll` is invoked. |
|
* |
|
* @param {function} callback Invoked when `notifyAll` is invoked. |
|
* @param {?object} context Context to call `callback` with. |
|
* @internal |
|
*/ |
|
|
|
|
|
CallbackQueue.prototype.enqueue = function enqueue(callback, context) { |
|
this._callbacks = this._callbacks || []; |
|
this._callbacks.push(callback); |
|
this._contexts = this._contexts || []; |
|
this._contexts.push(context); |
|
}; |
|
|
|
/** |
|
* Invokes all enqueued callbacks and clears the queue. This is invoked after |
|
* the DOM representation of a component has been created or updated. |
|
* |
|
* @internal |
|
*/ |
|
|
|
|
|
CallbackQueue.prototype.notifyAll = function notifyAll() { |
|
var callbacks = this._callbacks; |
|
var contexts = this._contexts; |
|
var arg = this._arg; |
|
if (callbacks && contexts) { |
|
!(callbacks.length === contexts.length) ? "development" !== 'production' ? invariant(false, 'Mismatched list of contexts in callback queue') : _prodInvariant('24') : void 0; |
|
this._callbacks = null; |
|
this._contexts = null; |
|
for (var i = 0; i < callbacks.length; i++) { |
|
callbacks[i].call(contexts[i], arg); |
|
} |
|
callbacks.length = 0; |
|
contexts.length = 0; |
|
} |
|
}; |
|
|
|
CallbackQueue.prototype.checkpoint = function checkpoint() { |
|
return this._callbacks ? this._callbacks.length : 0; |
|
}; |
|
|
|
CallbackQueue.prototype.rollback = function rollback(len) { |
|
if (this._callbacks && this._contexts) { |
|
this._callbacks.length = len; |
|
this._contexts.length = len; |
|
} |
|
}; |
|
|
|
/** |
|
* Resets the internal queue. |
|
* |
|
* @internal |
|
*/ |
|
|
|
|
|
CallbackQueue.prototype.reset = function reset() { |
|
this._callbacks = null; |
|
this._contexts = null; |
|
}; |
|
|
|
/** |
|
* `PooledClass` looks for this. |
|
*/ |
|
|
|
|
|
CallbackQueue.prototype.destructor = function destructor() { |
|
this.reset(); |
|
}; |
|
|
|
return CallbackQueue; |
|
}(); |
|
|
|
module.exports = PooledClass.addPoolingTo(CallbackQueue); |
|
},{"125":125,"150":150,"25":25}],7:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var EventPluginHub = _dereq_(17); |
|
var EventPropagators = _dereq_(20); |
|
var ExecutionEnvironment = _dereq_(136); |
|
var ReactDOMComponentTree = _dereq_(34); |
|
var ReactUpdates = _dereq_(82); |
|
var SyntheticEvent = _dereq_(91); |
|
|
|
var getEventTarget = _dereq_(114); |
|
var isEventSupported = _dereq_(122); |
|
var isTextInputElement = _dereq_(123); |
|
|
|
var eventTypes = { |
|
change: { |
|
phasedRegistrationNames: { |
|
bubbled: 'onChange', |
|
captured: 'onChangeCapture' |
|
}, |
|
dependencies: ['topBlur', 'topChange', 'topClick', 'topFocus', 'topInput', 'topKeyDown', 'topKeyUp', 'topSelectionChange'] |
|
} |
|
}; |
|
|
|
/** |
|
* For IE shims |
|
*/ |
|
var activeElement = null; |
|
var activeElementInst = null; |
|
var activeElementValue = null; |
|
var activeElementValueProp = null; |
|
|
|
/** |
|
* SECTION: handle `change` event |
|
*/ |
|
function shouldUseChangeEvent(elem) { |
|
var nodeName = elem.nodeName && elem.nodeName.toLowerCase(); |
|
return nodeName === 'select' || nodeName === 'input' && elem.type === 'file'; |
|
} |
|
|
|
var doesChangeEventBubble = false; |
|
if (ExecutionEnvironment.canUseDOM) { |
|
// See `handleChange` comment below |
|
doesChangeEventBubble = isEventSupported('change') && (!document.documentMode || document.documentMode > 8); |
|
} |
|
|
|
function manualDispatchChangeEvent(nativeEvent) { |
|
var event = SyntheticEvent.getPooled(eventTypes.change, activeElementInst, nativeEvent, getEventTarget(nativeEvent)); |
|
EventPropagators.accumulateTwoPhaseDispatches(event); |
|
|
|
// If change and propertychange bubbled, we'd just bind to it like all the |
|
// other events and have it go through ReactBrowserEventEmitter. Since it |
|
// doesn't, we manually listen for the events and so we have to enqueue and |
|
// process the abstract event manually. |
|
// |
|
// Batching is necessary here in order to ensure that all event handlers run |
|
// before the next rerender (including event handlers attached to ancestor |
|
// elements instead of directly on the input). Without this, controlled |
|
// components don't work properly in conjunction with event bubbling because |
|
// the component is rerendered and the value reverted before all the event |
|
// handlers can run. See https://github.com/facebook/react/issues/708. |
|
ReactUpdates.batchedUpdates(runEventInBatch, event); |
|
} |
|
|
|
function runEventInBatch(event) { |
|
EventPluginHub.enqueueEvents(event); |
|
EventPluginHub.processEventQueue(false); |
|
} |
|
|
|
function startWatchingForChangeEventIE8(target, targetInst) { |
|
activeElement = target; |
|
activeElementInst = targetInst; |
|
activeElement.attachEvent('onchange', manualDispatchChangeEvent); |
|
} |
|
|
|
function stopWatchingForChangeEventIE8() { |
|
if (!activeElement) { |
|
return; |
|
} |
|
activeElement.detachEvent('onchange', manualDispatchChangeEvent); |
|
activeElement = null; |
|
activeElementInst = null; |
|
} |
|
|
|
function getTargetInstForChangeEvent(topLevelType, targetInst) { |
|
if (topLevelType === 'topChange') { |
|
return targetInst; |
|
} |
|
} |
|
function handleEventsForChangeEventIE8(topLevelType, target, targetInst) { |
|
if (topLevelType === 'topFocus') { |
|
// stopWatching() should be a noop here but we call it just in case we |
|
// missed a blur event somehow. |
|
stopWatchingForChangeEventIE8(); |
|
startWatchingForChangeEventIE8(target, targetInst); |
|
} else if (topLevelType === '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. |
|
// IE10+ fire input events to often, such when a placeholder |
|
// changes or when an input with a placeholder is focused. |
|
isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 11); |
|
} |
|
|
|
/** |
|
* (For IE <=11) 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 IE <=11) Starts tracking propertychange events on the passed-in element |
|
* and override the value property so that we can distinguish user events from |
|
* value changes in JS. |
|
*/ |
|
function startWatchingForValueChange(target, targetInst) { |
|
activeElement = target; |
|
activeElementInst = targetInst; |
|
activeElementValue = target.value; |
|
activeElementValueProp = Object.getOwnPropertyDescriptor(target.constructor.prototype, 'value'); |
|
|
|
// Not guarded in a canDefineProperty check: IE8 supports defineProperty only |
|
// on DOM elements |
|
Object.defineProperty(activeElement, 'value', newValueProp); |
|
if (activeElement.attachEvent) { |
|
activeElement.attachEvent('onpropertychange', handlePropertyChange); |
|
} else { |
|
activeElement.addEventListener('propertychange', handlePropertyChange, false); |
|
} |
|
} |
|
|
|
/** |
|
* (For IE <=11) 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; |
|
|
|
if (activeElement.detachEvent) { |
|
activeElement.detachEvent('onpropertychange', handlePropertyChange); |
|
} else { |
|
activeElement.removeEventListener('propertychange', handlePropertyChange, false); |
|
} |
|
|
|
activeElement = null; |
|
activeElementInst = null; |
|
activeElementValue = null; |
|
activeElementValueProp = null; |
|
} |
|
|
|
/** |
|
* (For IE <=11) 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 getTargetInstForInputEvent(topLevelType, targetInst) { |
|
if (topLevelType === '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 targetInst; |
|
} |
|
} |
|
|
|
function handleEventsForInputEventIE(topLevelType, target, targetInst) { |
|
if (topLevelType === '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-11, propertychange fires for most input events but is buggy and |
|
// doesn't fire when text is deleted, but conveniently, selectionchange |
|
// appears to fire in all of the remaining cases so we catch those and |
|
// forward the event if the value has changed |
|
// 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(target, targetInst); |
|
} else if (topLevelType === 'topBlur') { |
|
stopWatchingForValueChange(); |
|
} |
|
} |
|
|
|
// For IE8 and IE9. |
|
function getTargetInstForInputEventIE(topLevelType, targetInst) { |
|
if (topLevelType === 'topSelectionChange' || topLevelType === 'topKeyUp' || topLevelType === '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 activeElementInst; |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* 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 && elem.nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio'); |
|
} |
|
|
|
function getTargetInstForClickEvent(topLevelType, targetInst) { |
|
if (topLevelType === 'topClick') { |
|
return targetInst; |
|
} |
|
} |
|
|
|
/** |
|
* 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, |
|
|
|
extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { |
|
var targetNode = targetInst ? ReactDOMComponentTree.getNodeFromInstance(targetInst) : window; |
|
|
|
var getTargetInstFunc, handleEventFunc; |
|
if (shouldUseChangeEvent(targetNode)) { |
|
if (doesChangeEventBubble) { |
|
getTargetInstFunc = getTargetInstForChangeEvent; |
|
} else { |
|
handleEventFunc = handleEventsForChangeEventIE8; |
|
} |
|
} else if (isTextInputElement(targetNode)) { |
|
if (isInputEventSupported) { |
|
getTargetInstFunc = getTargetInstForInputEvent; |
|
} else { |
|
getTargetInstFunc = getTargetInstForInputEventIE; |
|
handleEventFunc = handleEventsForInputEventIE; |
|
} |
|
} else if (shouldUseClickEvent(targetNode)) { |
|
getTargetInstFunc = getTargetInstForClickEvent; |
|
} |
|
|
|
if (getTargetInstFunc) { |
|
var inst = getTargetInstFunc(topLevelType, targetInst); |
|
if (inst) { |
|
var event = SyntheticEvent.getPooled(eventTypes.change, inst, nativeEvent, nativeEventTarget); |
|
event.type = 'change'; |
|
EventPropagators.accumulateTwoPhaseDispatches(event); |
|
return event; |
|
} |
|
} |
|
|
|
if (handleEventFunc) { |
|
handleEventFunc(topLevelType, targetNode, targetInst); |
|
} |
|
} |
|
|
|
}; |
|
|
|
module.exports = ChangeEventPlugin; |
|
},{"114":114,"122":122,"123":123,"136":136,"17":17,"20":20,"34":34,"82":82,"91":91}],8:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var DOMLazyTree = _dereq_(9); |
|
var Danger = _dereq_(13); |
|
var ReactDOMComponentTree = _dereq_(34); |
|
var ReactInstrumentation = _dereq_(64); |
|
|
|
var createMicrosoftUnsafeLocalFunction = _dereq_(105); |
|
var setInnerHTML = _dereq_(127); |
|
var setTextContent = _dereq_(128); |
|
|
|
function getNodeAfter(parentNode, node) { |
|
// Special case for text components, which return [open, close] comments |
|
// from getHostNode. |
|
if (Array.isArray(node)) { |
|
node = node[1]; |
|
} |
|
return node ? node.nextSibling : parentNode.firstChild; |
|
} |
|
|
|
/** |
|
* 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 |
|
*/ |
|
var insertChildAt = createMicrosoftUnsafeLocalFunction(function (parentNode, childNode, referenceNode) { |
|
// We rely exclusively on `insertBefore(node, null)` instead of also using |
|
// `appendChild(node)`. (Using `undefined` is not allowed by all browsers so |
|
// we are careful to use `null`.) |
|
parentNode.insertBefore(childNode, referenceNode); |
|
}); |
|
|
|
function insertLazyTreeChildAt(parentNode, childTree, referenceNode) { |
|
DOMLazyTree.insertTreeBefore(parentNode, childTree, referenceNode); |
|
} |
|
|
|
function moveChild(parentNode, childNode, referenceNode) { |
|
if (Array.isArray(childNode)) { |
|
moveDelimitedText(parentNode, childNode[0], childNode[1], referenceNode); |
|
} else { |
|
insertChildAt(parentNode, childNode, referenceNode); |
|
} |
|
} |
|
|
|
function removeChild(parentNode, childNode) { |
|
if (Array.isArray(childNode)) { |
|
var closingComment = childNode[1]; |
|
childNode = childNode[0]; |
|
removeDelimitedText(parentNode, childNode, closingComment); |
|
parentNode.removeChild(closingComment); |
|
} |
|
parentNode.removeChild(childNode); |
|
} |
|
|
|
function moveDelimitedText(parentNode, openingComment, closingComment, referenceNode) { |
|
var node = openingComment; |
|
while (true) { |
|
var nextNode = node.nextSibling; |
|
insertChildAt(parentNode, node, referenceNode); |
|
if (node === closingComment) { |
|
break; |
|
} |
|
node = nextNode; |
|
} |
|
} |
|
|
|
function removeDelimitedText(parentNode, startNode, closingComment) { |
|
while (true) { |
|
var node = startNode.nextSibling; |
|
if (node === closingComment) { |
|
// The closing comment is removed by ReactMultiChild. |
|
break; |
|
} else { |
|
parentNode.removeChild(node); |
|
} |
|
} |
|
} |
|
|
|
function replaceDelimitedText(openingComment, closingComment, stringText) { |
|
var parentNode = openingComment.parentNode; |
|
var nodeAfterComment = openingComment.nextSibling; |
|
if (nodeAfterComment === closingComment) { |
|
// There are no text nodes between the opening and closing comments; insert |
|
// a new one if stringText isn't empty. |
|
if (stringText) { |
|
insertChildAt(parentNode, document.createTextNode(stringText), nodeAfterComment); |
|
} |
|
} else { |
|
if (stringText) { |
|
// Set the text content of the first node after the opening comment, and |
|
// remove all following nodes up until the closing comment. |
|
setTextContent(nodeAfterComment, stringText); |
|
removeDelimitedText(parentNode, nodeAfterComment, closingComment); |
|
} else { |
|
removeDelimitedText(parentNode, openingComment, closingComment); |
|
} |
|
} |
|
|
|
if ("development" !== 'production') { |
|
ReactInstrumentation.debugTool.onHostOperation({ |
|
instanceID: ReactDOMComponentTree.getInstanceFromNode(openingComment)._debugID, |
|
type: 'replace text', |
|
payload: stringText |
|
}); |
|
} |
|
} |
|
|
|
var dangerouslyReplaceNodeWithMarkup = Danger.dangerouslyReplaceNodeWithMarkup; |
|
if ("development" !== 'production') { |
|
dangerouslyReplaceNodeWithMarkup = function (oldChild, markup, prevInstance) { |
|
Danger.dangerouslyReplaceNodeWithMarkup(oldChild, markup); |
|
if (prevInstance._debugID !== 0) { |
|
ReactInstrumentation.debugTool.onHostOperation({ |
|
instanceID: prevInstance._debugID, |
|
type: 'replace with', |
|
payload: markup.toString() |
|
}); |
|
} else { |
|
var nextInstance = ReactDOMComponentTree.getInstanceFromNode(markup.node); |
|
if (nextInstance._debugID !== 0) { |
|
ReactInstrumentation.debugTool.onHostOperation({ |
|
instanceID: nextInstance._debugID, |
|
type: 'mount', |
|
payload: markup.toString() |
|
}); |
|
} |
|
} |
|
}; |
|
} |
|
|
|
/** |
|
* Operations for updating with DOM children. |
|
*/ |
|
var DOMChildrenOperations = { |
|
|
|
dangerouslyReplaceNodeWithMarkup: dangerouslyReplaceNodeWithMarkup, |
|
|
|
replaceDelimitedText: replaceDelimitedText, |
|
|
|
/** |
|
* Updates a component's children by processing a series of updates. The |
|
* update configurations are each expected to have a `parentNode` property. |
|
* |
|
* @param {array<object>} updates List of update configurations. |
|
* @internal |
|
*/ |
|
processUpdates: function (parentNode, updates) { |
|
if ("development" !== 'production') { |
|
var parentNodeDebugID = ReactDOMComponentTree.getInstanceFromNode(parentNode)._debugID; |
|
} |
|
|
|
for (var k = 0; k < updates.length; k++) { |
|
var update = updates[k]; |
|
switch (update.type) { |
|
case 'INSERT_MARKUP': |
|
insertLazyTreeChildAt(parentNode, update.content, getNodeAfter(parentNode, update.afterNode)); |
|
if ("development" !== 'production') { |
|
ReactInstrumentation.debugTool.onHostOperation({ |
|
instanceID: parentNodeDebugID, |
|
type: 'insert child', |
|
payload: { toIndex: update.toIndex, content: update.content.toString() } |
|
}); |
|
} |
|
break; |
|
case 'MOVE_EXISTING': |
|
moveChild(parentNode, update.fromNode, getNodeAfter(parentNode, update.afterNode)); |
|
if ("development" !== 'production') { |
|
ReactInstrumentation.debugTool.onHostOperation({ |
|
instanceID: parentNodeDebugID, |
|
type: 'move child', |
|
payload: { fromIndex: update.fromIndex, toIndex: update.toIndex } |
|
}); |
|
} |
|
break; |
|
case 'SET_MARKUP': |
|
setInnerHTML(parentNode, update.content); |
|
if ("development" !== 'production') { |
|
ReactInstrumentation.debugTool.onHostOperation({ |
|
instanceID: parentNodeDebugID, |
|
type: 'replace children', |
|
payload: update.content.toString() |
|
}); |
|
} |
|
break; |
|
case 'TEXT_CONTENT': |
|
setTextContent(parentNode, update.content); |
|
if ("development" !== 'production') { |
|
ReactInstrumentation.debugTool.onHostOperation({ |
|
instanceID: parentNodeDebugID, |
|
type: 'replace text', |
|
payload: update.content.toString() |
|
}); |
|
} |
|
break; |
|
case 'REMOVE_NODE': |
|
removeChild(parentNode, update.fromNode); |
|
if ("development" !== 'production') { |
|
ReactInstrumentation.debugTool.onHostOperation({ |
|
instanceID: parentNodeDebugID, |
|
type: 'remove child', |
|
payload: { fromIndex: update.fromIndex } |
|
}); |
|
} |
|
break; |
|
} |
|
} |
|
} |
|
|
|
}; |
|
|
|
module.exports = DOMChildrenOperations; |
|
},{"105":105,"127":127,"128":128,"13":13,"34":34,"64":64,"9":9}],9:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2015-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var DOMNamespaces = _dereq_(10); |
|
var setInnerHTML = _dereq_(127); |
|
|
|
var createMicrosoftUnsafeLocalFunction = _dereq_(105); |
|
var setTextContent = _dereq_(128); |
|
|
|
var ELEMENT_NODE_TYPE = 1; |
|
var DOCUMENT_FRAGMENT_NODE_TYPE = 11; |
|
|
|
/** |
|
* In IE (8-11) and Edge, appending nodes with no children is dramatically |
|
* faster than appending a full subtree, so we essentially queue up the |
|
* .appendChild calls here and apply them so each node is added to its parent |
|
* before any children are added. |
|
* |
|
* In other browsers, doing so is slower or neutral compared to the other order |
|
* (in Firefox, twice as slow) so we only do this inversion in IE. |
|
* |
|
* See https://github.com/spicyj/innerhtml-vs-createelement-vs-clonenode. |
|
*/ |
|
var enableLazy = typeof document !== 'undefined' && typeof document.documentMode === 'number' || typeof navigator !== 'undefined' && typeof navigator.userAgent === 'string' && /\bEdge\/\d/.test(navigator.userAgent); |
|
|
|
function insertTreeChildren(tree) { |
|
if (!enableLazy) { |
|
return; |
|
} |
|
var node = tree.node; |
|
var children = tree.children; |
|
if (children.length) { |
|
for (var i = 0; i < children.length; i++) { |
|
insertTreeBefore(node, children[i], null); |
|
} |
|
} else if (tree.html != null) { |
|
setInnerHTML(node, tree.html); |
|
} else if (tree.text != null) { |
|
setTextContent(node, tree.text); |
|
} |
|
} |
|
|
|
var insertTreeBefore = createMicrosoftUnsafeLocalFunction(function (parentNode, tree, referenceNode) { |
|
// DocumentFragments aren't actually part of the DOM after insertion so |
|
// appending children won't update the DOM. We need to ensure the fragment |
|
// is properly populated first, breaking out of our lazy approach for just |
|
// this level. Also, some <object> plugins (like Flash Player) will read |
|
// <param> nodes immediately upon insertion into the DOM, so <object> |
|
// must also be populated prior to insertion into the DOM. |
|
if (tree.node.nodeType === DOCUMENT_FRAGMENT_NODE_TYPE || tree.node.nodeType === ELEMENT_NODE_TYPE && tree.node.nodeName.toLowerCase() === 'object' && (tree.node.namespaceURI == null || tree.node.namespaceURI === DOMNamespaces.html)) { |
|
insertTreeChildren(tree); |
|
parentNode.insertBefore(tree.node, referenceNode); |
|
} else { |
|
parentNode.insertBefore(tree.node, referenceNode); |
|
insertTreeChildren(tree); |
|
} |
|
}); |
|
|
|
function replaceChildWithTree(oldNode, newTree) { |
|
oldNode.parentNode.replaceChild(newTree.node, oldNode); |
|
insertTreeChildren(newTree); |
|
} |
|
|
|
function queueChild(parentTree, childTree) { |
|
if (enableLazy) { |
|
parentTree.children.push(childTree); |
|
} else { |
|
parentTree.node.appendChild(childTree.node); |
|
} |
|
} |
|
|
|
function queueHTML(tree, html) { |
|
if (enableLazy) { |
|
tree.html = html; |
|
} else { |
|
setInnerHTML(tree.node, html); |
|
} |
|
} |
|
|
|
function queueText(tree, text) { |
|
if (enableLazy) { |
|
tree.text = text; |
|
} else { |
|
setTextContent(tree.node, text); |
|
} |
|
} |
|
|
|
function toString() { |
|
return this.node.nodeName; |
|
} |
|
|
|
function DOMLazyTree(node) { |
|
return { |
|
node: node, |
|
children: [], |
|
html: null, |
|
text: null, |
|
toString: toString |
|
}; |
|
} |
|
|
|
DOMLazyTree.insertTreeBefore = insertTreeBefore; |
|
DOMLazyTree.replaceChildWithTree = replaceChildWithTree; |
|
DOMLazyTree.queueChild = queueChild; |
|
DOMLazyTree.queueHTML = queueHTML; |
|
DOMLazyTree.queueText = queueText; |
|
|
|
module.exports = DOMLazyTree; |
|
},{"10":10,"105":105,"127":127,"128":128}],10:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var DOMNamespaces = { |
|
html: 'http://www.w3.org/1999/xhtml', |
|
mathml: 'http://www.w3.org/1998/Math/MathML', |
|
svg: 'http://www.w3.org/2000/svg' |
|
}; |
|
|
|
module.exports = DOMNamespaces; |
|
},{}],11:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125); |
|
|
|
var invariant = _dereq_(150); |
|
|
|
function checkMask(value, bitmask) { |
|
return (value & bitmask) === bitmask; |
|
} |
|
|
|
var DOMPropertyInjection = { |
|
/** |
|
* Mapping from normalized, camelcased property names to a configuration that |
|
* specifies how the associated DOM property should be accessed or rendered. |
|
*/ |
|
MUST_USE_PROPERTY: 0x1, |
|
HAS_BOOLEAN_VALUE: 0x4, |
|
HAS_NUMERIC_VALUE: 0x8, |
|
HAS_POSITIVE_NUMERIC_VALUE: 0x10 | 0x8, |
|
HAS_OVERLOADED_BOOLEAN_VALUE: 0x20, |
|
|
|
/** |
|
* Inject some specialized knowledge about the DOM. This takes a config object |
|
* 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. |
|
* |
|
* DOMAttributeNamespaces: object mapping React attribute name to the DOM |
|
* attribute namespace URL. (Attribute names not specified use no namespace.) |
|
* |
|
* 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 Injection = DOMPropertyInjection; |
|
var Properties = domPropertyConfig.Properties || {}; |
|
var DOMAttributeNamespaces = domPropertyConfig.DOMAttributeNamespaces || {}; |
|
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) { |
|
!!DOMProperty.properties.hasOwnProperty(propName) ? "development" !== 'production' ? invariant(false, 'injectDOMPropertyConfig(...): You\'re trying to inject DOM property \'%s\' which has already been injected. You may be accidentally injecting the same DOM property config twice, or you may be injecting two configs that have conflicting property names.', propName) : _prodInvariant('48', propName) : void 0; |
|
|
|
var lowerCased = propName.toLowerCase(); |
|
var propConfig = Properties[propName]; |
|
|
|
var propertyInfo = { |
|
attributeName: lowerCased, |
|
attributeNamespace: null, |
|
propertyName: propName, |
|
mutationMethod: null, |
|
|
|
mustUseProperty: checkMask(propConfig, Injection.MUST_USE_PROPERTY), |
|
hasBooleanValue: checkMask(propConfig, Injection.HAS_BOOLEAN_VALUE), |
|
hasNumericValue: checkMask(propConfig, Injection.HAS_NUMERIC_VALUE), |
|
hasPositiveNumericValue: checkMask(propConfig, Injection.HAS_POSITIVE_NUMERIC_VALUE), |
|
hasOverloadedBooleanValue: checkMask(propConfig, Injection.HAS_OVERLOADED_BOOLEAN_VALUE) |
|
}; |
|
!(propertyInfo.hasBooleanValue + propertyInfo.hasNumericValue + propertyInfo.hasOverloadedBooleanValue <= 1) ? "development" !== 'production' ? invariant(false, 'DOMProperty: Value can be one of boolean, overloaded boolean, or numeric value, but not a combination: %s', propName) : _prodInvariant('50', propName) : void 0; |
|
|
|
if ("development" !== 'production') { |
|
DOMProperty.getPossibleStandardName[lowerCased] = propName; |
|
} |
|
|
|
if (DOMAttributeNames.hasOwnProperty(propName)) { |
|
var attributeName = DOMAttributeNames[propName]; |
|
propertyInfo.attributeName = attributeName; |
|
if ("development" !== 'production') { |
|
DOMProperty.getPossibleStandardName[attributeName] = propName; |
|
} |
|
} |
|
|
|
if (DOMAttributeNamespaces.hasOwnProperty(propName)) { |
|
propertyInfo.attributeNamespace = DOMAttributeNamespaces[propName]; |
|
} |
|
|
|
if (DOMPropertyNames.hasOwnProperty(propName)) { |
|
propertyInfo.propertyName = DOMPropertyNames[propName]; |
|
} |
|
|
|
if (DOMMutationMethods.hasOwnProperty(propName)) { |
|
propertyInfo.mutationMethod = DOMMutationMethods[propName]; |
|
} |
|
|
|
DOMProperty.properties[propName] = propertyInfo; |
|
} |
|
} |
|
}; |
|
|
|
/* eslint-disable max-len */ |
|
var ATTRIBUTE_NAME_START_CHAR = ':A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD'; |
|
/* eslint-enable max-len */ |
|
|
|
/** |
|
* DOMProperty exports lookup objects that can be used like functions: |
|
* |
|
* > 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', |
|
ROOT_ATTRIBUTE_NAME: 'data-reactroot', |
|
|
|
ATTRIBUTE_NAME_START_CHAR: ATTRIBUTE_NAME_START_CHAR, |
|
ATTRIBUTE_NAME_CHAR: ATTRIBUTE_NAME_START_CHAR + '\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040', |
|
|
|
/** |
|
* Map from property "standard name" to an object with info about how to set |
|
* the property in the DOM. Each object contains: |
|
* |
|
* attributeName: |
|
* Used when rendering markup or with `*Attribute()`. |
|
* attributeNamespace |
|
* propertyName: |
|
* Used on DOM node instances. (This includes properties that mutate due to |
|
* external factors.) |
|
* mutationMethod: |
|
* If non-null, used instead of the property or `setAttribute()` after |
|
* initial render. |
|
* mustUseProperty: |
|
* Whether the property must be accessed and mutated as an object property. |
|
* hasBooleanValue: |
|
* Whether the property should be removed when set to a falsey value. |
|
* hasNumericValue: |
|
* Whether the property must be numeric or parse as a numeric and should be |
|
* removed when set to a falsey value. |
|
* hasPositiveNumericValue: |
|
* Whether the property must be positive numeric or parse as a positive |
|
* numeric and should be removed when set to a falsey value. |
|
* hasOverloadedBooleanValue: |
|
* Whether the property can be used as a flag as well as with a value. |
|
* Removed when strictly equal to false; present without a value when |
|
* strictly equal to true; present with a value otherwise. |
|
*/ |
|
properties: {}, |
|
|
|
/** |
|
* Mapping from lowercase property names to the properly cased version, used |
|
* to warn in the case of missing properties. Available only in __DEV__. |
|
* |
|
* autofocus is predefined, because adding it to the property whitelist |
|
* causes unintended side effects. |
|
* |
|
* @type {Object} |
|
*/ |
|
getPossibleStandardName: "development" !== 'production' ? { autofocus: 'autoFocus' } : null, |
|
|
|
/** |
|
* 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; |
|
}, |
|
|
|
injection: DOMPropertyInjection |
|
}; |
|
|
|
module.exports = DOMProperty; |
|
},{"125":125,"150":150}],12:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var DOMProperty = _dereq_(11); |
|
var ReactDOMComponentTree = _dereq_(34); |
|
var ReactInstrumentation = _dereq_(64); |
|
|
|
var quoteAttributeValueForBrowser = _dereq_(124); |
|
var warning = _dereq_(157); |
|
|
|
var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + DOMProperty.ATTRIBUTE_NAME_START_CHAR + '][' + DOMProperty.ATTRIBUTE_NAME_CHAR + ']*$'); |
|
var illegalAttributeNameCache = {}; |
|
var validatedAttributeNameCache = {}; |
|
|
|
function isAttributeNameSafe(attributeName) { |
|
if (validatedAttributeNameCache.hasOwnProperty(attributeName)) { |
|
return true; |
|
} |
|
if (illegalAttributeNameCache.hasOwnProperty(attributeName)) { |
|
return false; |
|
} |
|
if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) { |
|
validatedAttributeNameCache[attributeName] = true; |
|
return true; |
|
} |
|
illegalAttributeNameCache[attributeName] = true; |
|
"development" !== 'production' ? warning(false, 'Invalid attribute name: `%s`', attributeName) : void 0; |
|
return false; |
|
} |
|
|
|
function shouldIgnoreValue(propertyInfo, value) { |
|
return value == null || propertyInfo.hasBooleanValue && !value || propertyInfo.hasNumericValue && isNaN(value) || propertyInfo.hasPositiveNumericValue && value < 1 || propertyInfo.hasOverloadedBooleanValue && value === false; |
|
} |
|
|
|
/** |
|
* 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 DOMProperty.ID_ATTRIBUTE_NAME + '=' + quoteAttributeValueForBrowser(id); |
|
}, |
|
|
|
setAttributeForID: function (node, id) { |
|
node.setAttribute(DOMProperty.ID_ATTRIBUTE_NAME, id); |
|
}, |
|
|
|
createMarkupForRoot: function () { |
|
return DOMProperty.ROOT_ATTRIBUTE_NAME + '=""'; |
|
}, |
|
|
|
setAttributeForRoot: function (node) { |
|
node.setAttribute(DOMProperty.ROOT_ATTRIBUTE_NAME, ''); |
|
}, |
|
|
|
/** |
|
* Creates markup for a property. |
|
* |
|
* @param {string} name |
|
* @param {*} value |
|
* @return {?string} Markup string, or null if the property was invalid. |
|
*/ |
|
createMarkupForProperty: function (name, value) { |
|
var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null; |
|
if (propertyInfo) { |
|
if (shouldIgnoreValue(propertyInfo, value)) { |
|
return ''; |
|
} |
|
var attributeName = propertyInfo.attributeName; |
|
if (propertyInfo.hasBooleanValue || propertyInfo.hasOverloadedBooleanValue && value === true) { |
|
return attributeName + '=""'; |
|
} |
|
return attributeName + '=' + quoteAttributeValueForBrowser(value); |
|
} else if (DOMProperty.isCustomAttribute(name)) { |
|
if (value == null) { |
|
return ''; |
|
} |
|
return name + '=' + quoteAttributeValueForBrowser(value); |
|
} |
|
return null; |
|
}, |
|
|
|
/** |
|
* Creates markup for a custom property. |
|
* |
|
* @param {string} name |
|
* @param {*} value |
|
* @return {string} Markup string, or empty string if the property was invalid. |
|
*/ |
|
createMarkupForCustomAttribute: function (name, value) { |
|
if (!isAttributeNameSafe(name) || value == null) { |
|
return ''; |
|
} |
|
return name + '=' + quoteAttributeValueForBrowser(value); |
|
}, |
|
|
|
/** |
|
* Sets the value for a property on a node. |
|
* |
|
* @param {DOMElement} node |
|
* @param {string} name |
|
* @param {*} value |
|
*/ |
|
setValueForProperty: function (node, name, value) { |
|
var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null; |
|
if (propertyInfo) { |
|
var mutationMethod = propertyInfo.mutationMethod; |
|
if (mutationMethod) { |
|
mutationMethod(node, value); |
|
} else if (shouldIgnoreValue(propertyInfo, value)) { |
|
this.deleteValueForProperty(node, name); |
|
return; |
|
} else if (propertyInfo.mustUseProperty) { |
|
// Contrary to `setAttribute`, object properties are properly |
|
// `toString`ed by IE8/9. |
|
node[propertyInfo.propertyName] = value; |
|
} else { |
|
var attributeName = propertyInfo.attributeName; |
|
var namespace = propertyInfo.attributeNamespace; |
|
// `setAttribute` with objects becomes only `[object]` in IE8/9, |
|
// ('' + value) makes it output the correct toString()-value. |
|
if (namespace) { |
|
node.setAttributeNS(namespace, attributeName, '' + value); |
|
} else if (propertyInfo.hasBooleanValue || propertyInfo.hasOverloadedBooleanValue && value === true) { |
|
node.setAttribute(attributeName, ''); |
|
} else { |
|
node.setAttribute(attributeName, '' + value); |
|
} |
|
} |
|
} else if (DOMProperty.isCustomAttribute(name)) { |
|
DOMPropertyOperations.setValueForAttribute(node, name, value); |
|
return; |
|
} |
|
|
|
if ("development" !== 'production') { |
|
var payload = {}; |
|
payload[name] = value; |
|
ReactInstrumentation.debugTool.onHostOperation({ |
|
instanceID: ReactDOMComponentTree.getInstanceFromNode(node)._debugID, |
|
type: 'update attribute', |
|
payload: payload |
|
}); |
|
} |
|
}, |
|
|
|
setValueForAttribute: function (node, name, value) { |
|
if (!isAttributeNameSafe(name)) { |
|
return; |
|
} |
|
if (value == null) { |
|
node.removeAttribute(name); |
|
} else { |
|
node.setAttribute(name, '' + value); |
|
} |
|
|
|
if ("development" !== 'production') { |
|
var payload = {}; |
|
payload[name] = value; |
|
ReactInstrumentation.debugTool.onHostOperation({ |
|
instanceID: ReactDOMComponentTree.getInstanceFromNode(node)._debugID, |
|
type: 'update attribute', |
|
payload: payload |
|
}); |
|
} |
|
}, |
|
|
|
/** |
|
* Deletes an attributes from a node. |
|
* |
|
* @param {DOMElement} node |
|
* @param {string} name |
|
*/ |
|
deleteValueForAttribute: function (node, name) { |
|
node.removeAttribute(name); |
|
if ("development" !== 'production') { |
|
ReactInstrumentation.debugTool.onHostOperation({ |
|
instanceID: ReactDOMComponentTree.getInstanceFromNode(node)._debugID, |
|
type: 'remove attribute', |
|
payload: name |
|
}); |
|
} |
|
}, |
|
|
|
/** |
|
* Deletes the value for a property on a node. |
|
* |
|
* @param {DOMElement} node |
|
* @param {string} name |
|
*/ |
|
deleteValueForProperty: function (node, name) { |
|
var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null; |
|
if (propertyInfo) { |
|
var mutationMethod = propertyInfo.mutationMethod; |
|
if (mutationMethod) { |
|
mutationMethod(node, undefined); |
|
} else if (propertyInfo.mustUseProperty) { |
|
var propName = propertyInfo.propertyName; |
|
if (propertyInfo.hasBooleanValue) { |
|
node[propName] = false; |
|
} else { |
|
node[propName] = ''; |
|
} |
|
} else { |
|
node.removeAttribute(propertyInfo.attributeName); |
|
} |
|
} else if (DOMProperty.isCustomAttribute(name)) { |
|
node.removeAttribute(name); |
|
} |
|
|
|
if ("development" !== 'production') { |
|
ReactInstrumentation.debugTool.onHostOperation({ |
|
instanceID: ReactDOMComponentTree.getInstanceFromNode(node)._debugID, |
|
type: 'remove attribute', |
|
payload: name |
|
}); |
|
} |
|
} |
|
|
|
}; |
|
|
|
module.exports = DOMPropertyOperations; |
|
},{"11":11,"124":124,"157":157,"34":34,"64":64}],13:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125); |
|
|
|
var DOMLazyTree = _dereq_(9); |
|
var ExecutionEnvironment = _dereq_(136); |
|
|
|
var createNodesFromMarkup = _dereq_(141); |
|
var emptyFunction = _dereq_(142); |
|
var invariant = _dereq_(150); |
|
|
|
var Danger = { |
|
|
|
/** |
|
* 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) { |
|
!ExecutionEnvironment.canUseDOM ? "development" !== 'production' ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Cannot render markup in a worker thread. Make sure `window` and `document` are available globally before requiring React when unit testing or use ReactDOMServer.renderToString() for server rendering.') : _prodInvariant('56') : void 0; |
|
!markup ? "development" !== 'production' ? invariant(false, 'dangerouslyReplaceNodeWithMarkup(...): Missing markup.') : _prodInvariant('57') : void 0; |
|
!(oldChild.nodeName !== 'HTML') ? "development" !== 'production' ? invariant(false, '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 ReactDOMServer.renderToString().') : _prodInvariant('58') : void 0; |
|
|
|
if (typeof markup === 'string') { |
|
var newChild = createNodesFromMarkup(markup, emptyFunction)[0]; |
|
oldChild.parentNode.replaceChild(newChild, oldChild); |
|
} else { |
|
DOMLazyTree.replaceChildWithTree(oldChild, markup); |
|
} |
|
} |
|
|
|
}; |
|
|
|
module.exports = Danger; |
|
},{"125":125,"136":136,"141":141,"142":142,"150":150,"9":9}],14:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
/** |
|
* 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 = ['ResponderEventPlugin', 'SimpleEventPlugin', 'TapEventPlugin', 'EnterLeaveEventPlugin', 'ChangeEventPlugin', 'SelectEventPlugin', 'BeforeInputEventPlugin']; |
|
|
|
module.exports = DefaultEventPluginOrder; |
|
},{}],15:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var EventPropagators = _dereq_(20); |
|
var ReactDOMComponentTree = _dereq_(34); |
|
var SyntheticMouseEvent = _dereq_(95); |
|
|
|
var eventTypes = { |
|
mouseEnter: { |
|
registrationName: 'onMouseEnter', |
|
dependencies: ['topMouseOut', 'topMouseOver'] |
|
}, |
|
mouseLeave: { |
|
registrationName: 'onMouseLeave', |
|
dependencies: ['topMouseOut', 'topMouseOver'] |
|
} |
|
}; |
|
|
|
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. |
|
*/ |
|
extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { |
|
if (topLevelType === 'topMouseOver' && (nativeEvent.relatedTarget || nativeEvent.fromElement)) { |
|
return null; |
|
} |
|
if (topLevelType !== 'topMouseOut' && topLevelType !== 'topMouseOver') { |
|
// Must not be a mouse in or mouse out - ignoring. |
|
return null; |
|
} |
|
|
|
var win; |
|
if (nativeEventTarget.window === nativeEventTarget) { |
|
// `nativeEventTarget` is probably a window object. |
|
win = nativeEventTarget; |
|
} else { |
|
// TODO: Figure out why `ownerDocument` is sometimes undefined in IE8. |
|
var doc = nativeEventTarget.ownerDocument; |
|
if (doc) { |
|
win = doc.defaultView || doc.parentWindow; |
|
} else { |
|
win = window; |
|
} |
|
} |
|
|
|
var from; |
|
var to; |
|
if (topLevelType === 'topMouseOut') { |
|
from = targetInst; |
|
var related = nativeEvent.relatedTarget || nativeEvent.toElement; |
|
to = related ? ReactDOMComponentTree.getClosestInstanceFromNode(related) : null; |
|
} else { |
|
// Moving to a node from outside the window. |
|
from = null; |
|
to = targetInst; |
|
} |
|
|
|
if (from === to) { |
|
// Nothing pertains to our managed components. |
|
return null; |
|
} |
|
|
|
var fromNode = from == null ? win : ReactDOMComponentTree.getNodeFromInstance(from); |
|
var toNode = to == null ? win : ReactDOMComponentTree.getNodeFromInstance(to); |
|
|
|
var leave = SyntheticMouseEvent.getPooled(eventTypes.mouseLeave, from, nativeEvent, nativeEventTarget); |
|
leave.type = 'mouseleave'; |
|
leave.target = fromNode; |
|
leave.relatedTarget = toNode; |
|
|
|
var enter = SyntheticMouseEvent.getPooled(eventTypes.mouseEnter, to, nativeEvent, nativeEventTarget); |
|
enter.type = 'mouseenter'; |
|
enter.target = toNode; |
|
enter.relatedTarget = fromNode; |
|
|
|
EventPropagators.accumulateEnterLeaveDispatches(leave, enter, from, to); |
|
|
|
return [leave, enter]; |
|
} |
|
|
|
}; |
|
|
|
module.exports = EnterLeaveEventPlugin; |
|
},{"20":20,"34":34,"95":95}],16:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
/** |
|
* Types of raw signals from the browser caught at the top level. |
|
*/ |
|
var topLevelTypes = { |
|
topAbort: null, |
|
topAnimationEnd: null, |
|
topAnimationIteration: null, |
|
topAnimationStart: null, |
|
topBlur: null, |
|
topCanPlay: null, |
|
topCanPlayThrough: 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, |
|
topDurationChange: null, |
|
topEmptied: null, |
|
topEncrypted: null, |
|
topEnded: null, |
|
topError: null, |
|
topFocus: null, |
|
topInput: null, |
|
topInvalid: null, |
|
topKeyDown: null, |
|
topKeyPress: null, |
|
topKeyUp: null, |
|
topLoad: null, |
|
topLoadedData: null, |
|
topLoadedMetadata: null, |
|
topLoadStart: null, |
|
topMouseDown: null, |
|
topMouseMove: null, |
|
topMouseOut: null, |
|
topMouseOver: null, |
|
topMouseUp: null, |
|
topPaste: null, |
|
topPause: null, |
|
topPlay: null, |
|
topPlaying: null, |
|
topProgress: null, |
|
topRateChange: null, |
|
topReset: null, |
|
topScroll: null, |
|
topSeeked: null, |
|
topSeeking: null, |
|
topSelectionChange: null, |
|
topStalled: null, |
|
topSubmit: null, |
|
topSuspend: null, |
|
topTextInput: null, |
|
topTimeUpdate: null, |
|
topTouchCancel: null, |
|
topTouchEnd: null, |
|
topTouchMove: null, |
|
topTouchStart: null, |
|
topTransitionEnd: null, |
|
topVolumeChange: null, |
|
topWaiting: null, |
|
topWheel: null |
|
}; |
|
|
|
var EventConstants = { |
|
topLevelTypes: topLevelTypes |
|
}; |
|
|
|
module.exports = EventConstants; |
|
},{}],17:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125); |
|
|
|
var EventPluginRegistry = _dereq_(18); |
|
var EventPluginUtils = _dereq_(19); |
|
var ReactErrorUtils = _dereq_(55); |
|
|
|
var accumulateInto = _dereq_(102); |
|
var forEachAccumulated = _dereq_(110); |
|
var invariant = _dereq_(150); |
|
|
|
/** |
|
* 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. |
|
* @param {boolean} simulated If the event is simulated (changes exn behavior) |
|
* @private |
|
*/ |
|
var executeDispatchesAndRelease = function (event, simulated) { |
|
if (event) { |
|
EventPluginUtils.executeDispatchesInOrder(event, simulated); |
|
|
|
if (!event.isPersistent()) { |
|
event.constructor.release(event); |
|
} |
|
} |
|
}; |
|
var executeDispatchesAndReleaseSimulated = function (e) { |
|
return executeDispatchesAndRelease(e, true); |
|
}; |
|
var executeDispatchesAndReleaseTopLevel = function (e) { |
|
return executeDispatchesAndRelease(e, false); |
|
}; |
|
|
|
var getDictionaryKey = function (inst) { |
|
// Prevents V8 performance issue: |
|
// https://github.com/facebook/react/pull/7232 |
|
return '.' + inst._rootNodeID; |
|
}; |
|
|
|
function isInteractive(tag) { |
|
return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea'; |
|
} |
|
|
|
function shouldPreventMouseEvent(name, type, props) { |
|
switch (name) { |
|
case 'onClick': |
|
case 'onClickCapture': |
|
case 'onDoubleClick': |
|
case 'onDoubleClickCapture': |
|
case 'onMouseDown': |
|
case 'onMouseDownCapture': |
|
case 'onMouseMove': |
|
case 'onMouseMoveCapture': |
|
case 'onMouseUp': |
|
case 'onMouseUpCapture': |
|
return !!(props.disabled && isInteractive(type)); |
|
default: |
|
return false; |
|
} |
|
} |
|
|
|
/** |
|
* 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 {array} InjectedEventPluginOrder |
|
* @public |
|
*/ |
|
injectEventPluginOrder: EventPluginRegistry.injectEventPluginOrder, |
|
|
|
/** |
|
* @param {object} injectedNamesToPlugins Map from names to plugin modules. |
|
*/ |
|
injectEventPluginsByName: EventPluginRegistry.injectEventPluginsByName |
|
|
|
}, |
|
|
|
/** |
|
* Stores `listener` at `listenerBank[registrationName][key]`. Is idempotent. |
|
* |
|
* @param {object} inst The instance, which is the source of events. |
|
* @param {string} registrationName Name of listener (e.g. `onClick`). |
|
* @param {function} listener The callback to store. |
|
*/ |
|
putListener: function (inst, registrationName, listener) { |
|
!(typeof listener === 'function') ? "development" !== 'production' ? invariant(false, 'Expected %s listener to be a function, instead got type %s', registrationName, typeof listener) : _prodInvariant('94', registrationName, typeof listener) : void 0; |
|
|
|
var key = getDictionaryKey(inst); |
|
var bankForRegistrationName = listenerBank[registrationName] || (listenerBank[registrationName] = {}); |
|
bankForRegistrationName[key] = listener; |
|
|
|
var PluginModule = EventPluginRegistry.registrationNameModules[registrationName]; |
|
if (PluginModule && PluginModule.didPutListener) { |
|
PluginModule.didPutListener(inst, registrationName, listener); |
|
} |
|
}, |
|
|
|
/** |
|
* @param {object} inst The instance, which is the source of events. |
|
* @param {string} registrationName Name of listener (e.g. `onClick`). |
|
* @return {?function} The stored callback. |
|
*/ |
|
getListener: function (inst, registrationName) { |
|
// TODO: shouldPreventMouseEvent is DOM-specific and definitely should not |
|
// live here; needs to be moved to a better place soon |
|
var bankForRegistrationName = listenerBank[registrationName]; |
|
if (shouldPreventMouseEvent(registrationName, inst._currentElement.type, inst._currentElement.props)) { |
|
return null; |
|
} |
|
var key = getDictionaryKey(inst); |
|
return bankForRegistrationName && bankForRegistrationName[key]; |
|
}, |
|
|
|
/** |
|
* Deletes a listener from the registration bank. |
|
* |
|
* @param {object} inst The instance, which is the source of events. |
|
* @param {string} registrationName Name of listener (e.g. `onClick`). |
|
*/ |
|
deleteListener: function (inst, registrationName) { |
|
var PluginModule = EventPluginRegistry.registrationNameModules[registrationName]; |
|
if (PluginModule && PluginModule.willDeleteListener) { |
|
PluginModule.willDeleteListener(inst, registrationName); |
|
} |
|
|
|
var bankForRegistrationName = listenerBank[registrationName]; |
|
// TODO: This should never be null -- when is it? |
|
if (bankForRegistrationName) { |
|
var key = getDictionaryKey(inst); |
|
delete bankForRegistrationName[key]; |
|
} |
|
}, |
|
|
|
/** |
|
* Deletes all listeners for the DOM element with the supplied ID. |
|
* |
|
* @param {object} inst The instance, which is the source of events. |
|
*/ |
|
deleteAllListeners: function (inst) { |
|
var key = getDictionaryKey(inst); |
|
for (var registrationName in listenerBank) { |
|
if (!listenerBank.hasOwnProperty(registrationName)) { |
|
continue; |
|
} |
|
|
|
if (!listenerBank[registrationName][key]) { |
|
continue; |
|
} |
|
|
|
var PluginModule = EventPluginRegistry.registrationNameModules[registrationName]; |
|
if (PluginModule && PluginModule.willDeleteListener) { |
|
PluginModule.willDeleteListener(inst, registrationName); |
|
} |
|
|
|
delete listenerBank[registrationName][key]; |
|
} |
|
}, |
|
|
|
/** |
|
* Allows registered plugins an opportunity to extract events from top-level |
|
* native browser events. |
|
* |
|
* @return {*} An accumulation of synthetic events. |
|
* @internal |
|
*/ |
|
extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { |
|
var events; |
|
var plugins = EventPluginRegistry.plugins; |
|
for (var i = 0; i < plugins.length; i++) { |
|
// Not every plugin in the ordering may be loaded at runtime. |
|
var possiblePlugin = plugins[i]; |
|
if (possiblePlugin) { |
|
var extractedEvents = possiblePlugin.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget); |
|
if (extractedEvents) { |
|
events = accumulateInto(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 = accumulateInto(eventQueue, events); |
|
} |
|
}, |
|
|
|
/** |
|
* Dispatches all synthetic events on the event queue. |
|
* |
|
* @internal |
|
*/ |
|
processEventQueue: function (simulated) { |
|
// Set `eventQueue` to null before processing it so that we can tell if more |
|
// events get enqueued while processing. |
|
var processingEventQueue = eventQueue; |
|
eventQueue = null; |
|
if (simulated) { |
|
forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseSimulated); |
|
} else { |
|
forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel); |
|
} |
|
!!eventQueue ? "development" !== 'production' ? invariant(false, 'processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented.') : _prodInvariant('95') : void 0; |
|
// This would be a good time to rethrow if any of the event handlers threw. |
|
ReactErrorUtils.rethrowCaughtError(); |
|
}, |
|
|
|
/** |
|
* These are needed for tests only. Do not use! |
|
*/ |
|
__purge: function () { |
|
listenerBank = {}; |
|
}, |
|
|
|
__getListenerBank: function () { |
|
return listenerBank; |
|
} |
|
|
|
}; |
|
|
|
module.exports = EventPluginHub; |
|
},{"102":102,"110":110,"125":125,"150":150,"18":18,"19":19,"55":55}],18:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125); |
|
|
|
var invariant = _dereq_(150); |
|
|
|
/** |
|
* 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); |
|
!(pluginIndex > -1) ? "development" !== 'production' ? invariant(false, 'EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `%s`.', pluginName) : _prodInvariant('96', pluginName) : void 0; |
|
if (EventPluginRegistry.plugins[pluginIndex]) { |
|
continue; |
|
} |
|
!pluginModule.extractEvents ? "development" !== 'production' ? invariant(false, 'EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `%s` does not.', pluginName) : _prodInvariant('97', pluginName) : void 0; |
|
EventPluginRegistry.plugins[pluginIndex] = pluginModule; |
|
var publishedEvents = pluginModule.eventTypes; |
|
for (var eventName in publishedEvents) { |
|
!publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName) ? "development" !== 'production' ? invariant(false, 'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.', eventName, pluginName) : _prodInvariant('98', eventName, pluginName) : void 0; |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* 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) { |
|
!!EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName) ? "development" !== 'production' ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same event name, `%s`.', eventName) : _prodInvariant('99', eventName) : void 0; |
|
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) { |
|
!!EventPluginRegistry.registrationNameModules[registrationName] ? "development" !== 'production' ? invariant(false, 'EventPluginHub: More than one plugin attempted to publish the same registration name, `%s`.', registrationName) : _prodInvariant('100', registrationName) : void 0; |
|
EventPluginRegistry.registrationNameModules[registrationName] = pluginModule; |
|
EventPluginRegistry.registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies; |
|
|
|
if ("development" !== 'production') { |
|
var lowerCasedName = registrationName.toLowerCase(); |
|
EventPluginRegistry.possibleRegistrationNames[lowerCasedName] = registrationName; |
|
|
|
if (registrationName === 'onDoubleClick') { |
|
EventPluginRegistry.possibleRegistrationNames.ondblclick = registrationName; |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* 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: {}, |
|
|
|
/** |
|
* Mapping from lowercase registration names to the properly cased version, |
|
* used to warn in the case of missing event handlers. Available |
|
* only in __DEV__. |
|
* @type {Object} |
|
*/ |
|
possibleRegistrationNames: "development" !== 'production' ? {} : null, |
|
// Trust the developer to only use possibleRegistrationNames in __DEV__ |
|
|
|
/** |
|
* 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) { |
|
!!eventPluginOrder ? "development" !== 'production' ? invariant(false, 'EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React.') : _prodInvariant('101') : void 0; |
|
// 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.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== pluginModule) { |
|
!!namesToPlugins[pluginName] ? "development" !== 'production' ? invariant(false, 'EventPluginRegistry: Cannot inject two different event plugins using the same name, `%s`.', pluginName) : _prodInvariant('102', pluginName) : void 0; |
|
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; |
|
} |
|
if (dispatchConfig.phasedRegistrationNames !== undefined) { |
|
// pulling phasedRegistrationNames out of dispatchConfig helps Flow see |
|
// that it is not undefined. |
|
var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; |
|
|
|
for (var phase in phasedRegistrationNames) { |
|
if (!phasedRegistrationNames.hasOwnProperty(phase)) { |
|
continue; |
|
} |
|
var pluginModule = EventPluginRegistry.registrationNameModules[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]; |
|
} |
|
} |
|
|
|
if ("development" !== 'production') { |
|
var possibleRegistrationNames = EventPluginRegistry.possibleRegistrationNames; |
|
for (var lowerCasedName in possibleRegistrationNames) { |
|
if (possibleRegistrationNames.hasOwnProperty(lowerCasedName)) { |
|
delete possibleRegistrationNames[lowerCasedName]; |
|
} |
|
} |
|
} |
|
} |
|
|
|
}; |
|
|
|
module.exports = EventPluginRegistry; |
|
},{"125":125,"150":150}],19:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125); |
|
|
|
var ReactErrorUtils = _dereq_(55); |
|
|
|
var invariant = _dereq_(150); |
|
var warning = _dereq_(157); |
|
|
|
/** |
|
* Injected dependencies: |
|
*/ |
|
|
|
/** |
|
* - `ComponentTree`: [required] Module that can convert between React instances |
|
* and actual node references. |
|
*/ |
|
var ComponentTree; |
|
var TreeTraversal; |
|
var injection = { |
|
injectComponentTree: function (Injected) { |
|
ComponentTree = Injected; |
|
if ("development" !== 'production') { |
|
"development" !== 'production' ? warning(Injected && Injected.getNodeFromInstance && Injected.getInstanceFromNode, 'EventPluginUtils.injection.injectComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.') : void 0; |
|
} |
|
}, |
|
injectTreeTraversal: function (Injected) { |
|
TreeTraversal = Injected; |
|
if ("development" !== 'production') { |
|
"development" !== 'production' ? warning(Injected && Injected.isAncestor && Injected.getLowestCommonAncestor, 'EventPluginUtils.injection.injectTreeTraversal(...): Injected ' + 'module is missing isAncestor or getLowestCommonAncestor.') : void 0; |
|
} |
|
} |
|
}; |
|
|
|
function isEndish(topLevelType) { |
|
return topLevelType === 'topMouseUp' || topLevelType === 'topTouchEnd' || topLevelType === 'topTouchCancel'; |
|
} |
|
|
|
function isMoveish(topLevelType) { |
|
return topLevelType === 'topMouseMove' || topLevelType === 'topTouchMove'; |
|
} |
|
function isStartish(topLevelType) { |
|
return topLevelType === 'topMouseDown' || topLevelType === 'topTouchStart'; |
|
} |
|
|
|
var validateEventDispatches; |
|
if ("development" !== 'production') { |
|
validateEventDispatches = function (event) { |
|
var dispatchListeners = event._dispatchListeners; |
|
var dispatchInstances = event._dispatchInstances; |
|
|
|
var listenersIsArr = Array.isArray(dispatchListeners); |
|
var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0; |
|
|
|
var instancesIsArr = Array.isArray(dispatchInstances); |
|
var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0; |
|
|
|
"development" !== 'production' ? warning(instancesIsArr === listenersIsArr && instancesLen === listenersLen, 'EventPluginUtils: Invalid `event`.') : void 0; |
|
}; |
|
} |
|
|
|
/** |
|
* Dispatch the event to the listener. |
|
* @param {SyntheticEvent} event SyntheticEvent to handle |
|
* @param {boolean} simulated If the event is simulated (changes exn behavior) |
|
* @param {function} listener Application-level callback |
|
* @param {*} inst Internal component instance |
|
*/ |
|
function executeDispatch(event, simulated, listener, inst) { |
|
var type = event.type || 'unknown-event'; |
|
event.currentTarget = EventPluginUtils.getNodeFromInstance(inst); |
|
if (simulated) { |
|
ReactErrorUtils.invokeGuardedCallbackWithCatch(type, listener, event); |
|
} else { |
|
ReactErrorUtils.invokeGuardedCallback(type, listener, event); |
|
} |
|
event.currentTarget = null; |
|
} |
|
|
|
/** |
|
* Standard/simple iteration through an event's collected dispatches. |
|
*/ |
|
function executeDispatchesInOrder(event, simulated) { |
|
var dispatchListeners = event._dispatchListeners; |
|
var dispatchInstances = event._dispatchInstances; |
|
if ("development" !== 'production') { |
|
validateEventDispatches(event); |
|
} |
|
if (Array.isArray(dispatchListeners)) { |
|
for (var i = 0; i < dispatchListeners.length; i++) { |
|
if (event.isPropagationStopped()) { |
|
break; |
|
} |
|
// Listeners and Instances are two parallel arrays that are always in sync. |
|
executeDispatch(event, simulated, dispatchListeners[i], dispatchInstances[i]); |
|
} |
|
} else if (dispatchListeners) { |
|
executeDispatch(event, simulated, dispatchListeners, dispatchInstances); |
|
} |
|
event._dispatchListeners = null; |
|
event._dispatchInstances = null; |
|
} |
|
|
|
/** |
|
* Standard/simple iteration through an event's collected dispatches, but stops |
|
* at the first dispatch execution returning true, and returns that id. |
|
* |
|
* @return {?string} id of the first dispatch execution who's listener returns |
|
* true, or null if no listener returned true. |
|
*/ |
|
function executeDispatchesInOrderStopAtTrueImpl(event) { |
|
var dispatchListeners = event._dispatchListeners; |
|
var dispatchInstances = event._dispatchInstances; |
|
if ("development" !== 'production') { |
|
validateEventDispatches(event); |
|
} |
|
if (Array.isArray(dispatchListeners)) { |
|
for (var i = 0; i < dispatchListeners.length; i++) { |
|
if (event.isPropagationStopped()) { |
|
break; |
|
} |
|
// Listeners and Instances are two parallel arrays that are always in sync. |
|
if (dispatchListeners[i](event, dispatchInstances[i])) { |
|
return dispatchInstances[i]; |
|
} |
|
} |
|
} else if (dispatchListeners) { |
|
if (dispatchListeners(event, dispatchInstances)) { |
|
return dispatchInstances; |
|
} |
|
} |
|
return null; |
|
} |
|
|
|
/** |
|
* @see executeDispatchesInOrderStopAtTrueImpl |
|
*/ |
|
function executeDispatchesInOrderStopAtTrue(event) { |
|
var ret = executeDispatchesInOrderStopAtTrueImpl(event); |
|
event._dispatchInstances = null; |
|
event._dispatchListeners = null; |
|
return ret; |
|
} |
|
|
|
/** |
|
* 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 ("development" !== 'production') { |
|
validateEventDispatches(event); |
|
} |
|
var dispatchListener = event._dispatchListeners; |
|
var dispatchInstance = event._dispatchInstances; |
|
!!Array.isArray(dispatchListener) ? "development" !== 'production' ? invariant(false, 'executeDirectDispatch(...): Invalid `event`.') : _prodInvariant('103') : void 0; |
|
event.currentTarget = dispatchListener ? EventPluginUtils.getNodeFromInstance(dispatchInstance) : null; |
|
var res = dispatchListener ? dispatchListener(event) : null; |
|
event.currentTarget = null; |
|
event._dispatchListeners = null; |
|
event._dispatchInstances = null; |
|
return res; |
|
} |
|
|
|
/** |
|
* @param {SyntheticEvent} event |
|
* @return {boolean} 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, |
|
executeDispatchesInOrder: executeDispatchesInOrder, |
|
executeDispatchesInOrderStopAtTrue: executeDispatchesInOrderStopAtTrue, |
|
hasDispatches: hasDispatches, |
|
|
|
getInstanceFromNode: function (node) { |
|
return ComponentTree.getInstanceFromNode(node); |
|
}, |
|
getNodeFromInstance: function (node) { |
|
return ComponentTree.getNodeFromInstance(node); |
|
}, |
|
isAncestor: function (a, b) { |
|
return TreeTraversal.isAncestor(a, b); |
|
}, |
|
getLowestCommonAncestor: function (a, b) { |
|
return TreeTraversal.getLowestCommonAncestor(a, b); |
|
}, |
|
getParentInstance: function (inst) { |
|
return TreeTraversal.getParentInstance(inst); |
|
}, |
|
traverseTwoPhase: function (target, fn, arg) { |
|
return TreeTraversal.traverseTwoPhase(target, fn, arg); |
|
}, |
|
traverseEnterLeave: function (from, to, fn, argFrom, argTo) { |
|
return TreeTraversal.traverseEnterLeave(from, to, fn, argFrom, argTo); |
|
}, |
|
|
|
injection: injection |
|
}; |
|
|
|
module.exports = EventPluginUtils; |
|
},{"125":125,"150":150,"157":157,"55":55}],20:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var EventPluginHub = _dereq_(17); |
|
var EventPluginUtils = _dereq_(19); |
|
|
|
var accumulateInto = _dereq_(102); |
|
var forEachAccumulated = _dereq_(110); |
|
var warning = _dereq_(157); |
|
|
|
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(inst, event, propagationPhase) { |
|
var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase]; |
|
return getListener(inst, 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(inst, phase, event) { |
|
if ("development" !== 'production') { |
|
"development" !== 'production' ? warning(inst, 'Dispatching inst must not be null') : void 0; |
|
} |
|
var listener = listenerAtPhase(inst, event, phase); |
|
if (listener) { |
|
event._dispatchListeners = accumulateInto(event._dispatchListeners, listener); |
|
event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); |
|
} |
|
} |
|
|
|
/** |
|
* 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 cannot 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) { |
|
EventPluginUtils.traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event); |
|
} |
|
} |
|
|
|
/** |
|
* Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID. |
|
*/ |
|
function accumulateTwoPhaseDispatchesSingleSkipTarget(event) { |
|
if (event && event.dispatchConfig.phasedRegistrationNames) { |
|
var targetInst = event._targetInst; |
|
var parentInst = targetInst ? EventPluginUtils.getParentInstance(targetInst) : null; |
|
EventPluginUtils.traverseTwoPhase(parentInst, 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(inst, ignoredDirection, event) { |
|
if (event && event.dispatchConfig.registrationName) { |
|
var registrationName = event.dispatchConfig.registrationName; |
|
var listener = getListener(inst, registrationName); |
|
if (listener) { |
|
event._dispatchListeners = accumulateInto(event._dispatchListeners, listener); |
|
event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* Accumulates dispatches on an `SyntheticEvent`, but only for the |
|
* `dispatchMarker`. |
|
* @param {SyntheticEvent} event |
|
*/ |
|
function accumulateDirectDispatchesSingle(event) { |
|
if (event && event.dispatchConfig.registrationName) { |
|
accumulateDispatches(event._targetInst, null, event); |
|
} |
|
} |
|
|
|
function accumulateTwoPhaseDispatches(events) { |
|
forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle); |
|
} |
|
|
|
function accumulateTwoPhaseDispatchesSkipTarget(events) { |
|
forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget); |
|
} |
|
|
|
function accumulateEnterLeaveDispatches(leave, enter, from, to) { |
|
EventPluginUtils.traverseEnterLeave(from, to, 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, |
|
accumulateTwoPhaseDispatchesSkipTarget: accumulateTwoPhaseDispatchesSkipTarget, |
|
accumulateDirectDispatches: accumulateDirectDispatches, |
|
accumulateEnterLeaveDispatches: accumulateEnterLeaveDispatches |
|
}; |
|
|
|
module.exports = EventPropagators; |
|
},{"102":102,"110":110,"157":157,"17":17,"19":19}],21:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _assign = _dereq_(158); |
|
|
|
var PooledClass = _dereq_(25); |
|
|
|
var getTextContentAccessor = _dereq_(119); |
|
|
|
/** |
|
* This helper class stores information about text content of a target node, |
|
* allowing comparison of content before and after a given event. |
|
* |
|
* Identify the node where selection currently begins, then observe |
|
* both its text content and its current position in the DOM. Since the |
|
* browser may natively replace the target node during composition, we can |
|
* use its position to find its replacement. |
|
* |
|
* @param {DOMEventTarget} root |
|
*/ |
|
function FallbackCompositionState(root) { |
|
this._root = root; |
|
this._startText = this.getText(); |
|
this._fallbackText = null; |
|
} |
|
|
|
_assign(FallbackCompositionState.prototype, { |
|
destructor: function () { |
|
this._root = null; |
|
this._startText = null; |
|
this._fallbackText = null; |
|
}, |
|
|
|
/** |
|
* Get current text of input. |
|
* |
|
* @return {string} |
|
*/ |
|
getText: function () { |
|
if ('value' in this._root) { |
|
return this._root.value; |
|
} |
|
return this._root[getTextContentAccessor()]; |
|
}, |
|
|
|
/** |
|
* Determine the differing substring between the initially stored |
|
* text content and the current content. |
|
* |
|
* @return {string} |
|
*/ |
|
getData: function () { |
|
if (this._fallbackText) { |
|
return this._fallbackText; |
|
} |
|
|
|
var start; |
|
var startValue = this._startText; |
|
var startLength = startValue.length; |
|
var end; |
|
var endValue = this.getText(); |
|
var endLength = endValue.length; |
|
|
|
for (start = 0; start < startLength; start++) { |
|
if (startValue[start] !== endValue[start]) { |
|
break; |
|
} |
|
} |
|
|
|
var minEnd = startLength - start; |
|
for (end = 1; end <= minEnd; end++) { |
|
if (startValue[startLength - end] !== endValue[endLength - end]) { |
|
break; |
|
} |
|
} |
|
|
|
var sliceTail = end > 1 ? 1 - end : undefined; |
|
this._fallbackText = endValue.slice(start, sliceTail); |
|
return this._fallbackText; |
|
} |
|
}); |
|
|
|
PooledClass.addPoolingTo(FallbackCompositionState); |
|
|
|
module.exports = FallbackCompositionState; |
|
},{"119":119,"158":158,"25":25}],22:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var DOMProperty = _dereq_(11); |
|
|
|
var MUST_USE_PROPERTY = DOMProperty.injection.MUST_USE_PROPERTY; |
|
var HAS_BOOLEAN_VALUE = DOMProperty.injection.HAS_BOOLEAN_VALUE; |
|
var HAS_NUMERIC_VALUE = DOMProperty.injection.HAS_NUMERIC_VALUE; |
|
var HAS_POSITIVE_NUMERIC_VALUE = DOMProperty.injection.HAS_POSITIVE_NUMERIC_VALUE; |
|
var HAS_OVERLOADED_BOOLEAN_VALUE = DOMProperty.injection.HAS_OVERLOADED_BOOLEAN_VALUE; |
|
|
|
var HTMLDOMPropertyConfig = { |
|
isCustomAttribute: RegExp.prototype.test.bind(new RegExp('^(data|aria)-[' + DOMProperty.ATTRIBUTE_NAME_CHAR + ']*$')), |
|
Properties: { |
|
/** |
|
* Standard Properties |
|
*/ |
|
accept: 0, |
|
acceptCharset: 0, |
|
accessKey: 0, |
|
action: 0, |
|
allowFullScreen: HAS_BOOLEAN_VALUE, |
|
allowTransparency: 0, |
|
alt: 0, |
|
// specifies target context for links with `preload` type |
|
as: 0, |
|
async: HAS_BOOLEAN_VALUE, |
|
autoComplete: 0, |
|
// autoFocus is polyfilled/normalized by AutoFocusUtils |
|
// autoFocus: HAS_BOOLEAN_VALUE, |
|
autoPlay: HAS_BOOLEAN_VALUE, |
|
capture: HAS_BOOLEAN_VALUE, |
|
cellPadding: 0, |
|
cellSpacing: 0, |
|
charSet: 0, |
|
challenge: 0, |
|
checked: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, |
|
cite: 0, |
|
classID: 0, |
|
className: 0, |
|
cols: HAS_POSITIVE_NUMERIC_VALUE, |
|
colSpan: 0, |
|
content: 0, |
|
contentEditable: 0, |
|
contextMenu: 0, |
|
controls: HAS_BOOLEAN_VALUE, |
|
coords: 0, |
|
crossOrigin: 0, |
|
data: 0, // For `<object />` acts as `src`. |
|
dateTime: 0, |
|
'default': HAS_BOOLEAN_VALUE, |
|
defer: HAS_BOOLEAN_VALUE, |
|
dir: 0, |
|
disabled: HAS_BOOLEAN_VALUE, |
|
download: HAS_OVERLOADED_BOOLEAN_VALUE, |
|
draggable: 0, |
|
encType: 0, |
|
form: 0, |
|
formAction: 0, |
|
formEncType: 0, |
|
formMethod: 0, |
|
formNoValidate: HAS_BOOLEAN_VALUE, |
|
formTarget: 0, |
|
frameBorder: 0, |
|
headers: 0, |
|
height: 0, |
|
hidden: HAS_BOOLEAN_VALUE, |
|
high: 0, |
|
href: 0, |
|
hrefLang: 0, |
|
htmlFor: 0, |
|
httpEquiv: 0, |
|
icon: 0, |
|
id: 0, |
|
inputMode: 0, |
|
integrity: 0, |
|
is: 0, |
|
keyParams: 0, |
|
keyType: 0, |
|
kind: 0, |
|
label: 0, |
|
lang: 0, |
|
list: 0, |
|
loop: HAS_BOOLEAN_VALUE, |
|
low: 0, |
|
manifest: 0, |
|
marginHeight: 0, |
|
marginWidth: 0, |
|
max: 0, |
|
maxLength: 0, |
|
media: 0, |
|
mediaGroup: 0, |
|
method: 0, |
|
min: 0, |
|
minLength: 0, |
|
// Caution; `option.selected` is not updated if `select.multiple` is |
|
// disabled with `removeAttribute`. |
|
multiple: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, |
|
muted: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, |
|
name: 0, |
|
nonce: 0, |
|
noValidate: HAS_BOOLEAN_VALUE, |
|
open: HAS_BOOLEAN_VALUE, |
|
optimum: 0, |
|
pattern: 0, |
|
placeholder: 0, |
|
playsInline: HAS_BOOLEAN_VALUE, |
|
poster: 0, |
|
preload: 0, |
|
profile: 0, |
|
radioGroup: 0, |
|
readOnly: HAS_BOOLEAN_VALUE, |
|
referrerPolicy: 0, |
|
rel: 0, |
|
required: HAS_BOOLEAN_VALUE, |
|
reversed: HAS_BOOLEAN_VALUE, |
|
role: 0, |
|
rows: HAS_POSITIVE_NUMERIC_VALUE, |
|
rowSpan: HAS_NUMERIC_VALUE, |
|
sandbox: 0, |
|
scope: 0, |
|
scoped: HAS_BOOLEAN_VALUE, |
|
scrolling: 0, |
|
seamless: HAS_BOOLEAN_VALUE, |
|
selected: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, |
|
shape: 0, |
|
size: HAS_POSITIVE_NUMERIC_VALUE, |
|
sizes: 0, |
|
span: HAS_POSITIVE_NUMERIC_VALUE, |
|
spellCheck: 0, |
|
src: 0, |
|
srcDoc: 0, |
|
srcLang: 0, |
|
srcSet: 0, |
|
start: HAS_NUMERIC_VALUE, |
|
step: 0, |
|
style: 0, |
|
summary: 0, |
|
tabIndex: 0, |
|
target: 0, |
|
title: 0, |
|
// Setting .type throws on non-<input> tags |
|
type: 0, |
|
useMap: 0, |
|
value: 0, |
|
width: 0, |
|
wmode: 0, |
|
wrap: 0, |
|
|
|
/** |
|
* RDFa Properties |
|
*/ |
|
about: 0, |
|
datatype: 0, |
|
inlist: 0, |
|
prefix: 0, |
|
// property is also supported for OpenGraph in meta tags. |
|
property: 0, |
|
resource: 0, |
|
'typeof': 0, |
|
vocab: 0, |
|
|
|
/** |
|
* Non-standard Properties |
|
*/ |
|
// autoCapitalize and autoCorrect are supported in Mobile Safari for |
|
// keyboard hints. |
|
autoCapitalize: 0, |
|
autoCorrect: 0, |
|
// autoSave allows WebKit/Blink to persist values of input fields on page reloads |
|
autoSave: 0, |
|
// color is for Safari mask-icon link |
|
color: 0, |
|
// itemProp, itemScope, itemType are for |
|
// Microdata support. See http://schema.org/docs/gs.html |
|
itemProp: 0, |
|
itemScope: HAS_BOOLEAN_VALUE, |
|
itemType: 0, |
|
// itemID and itemRef are for Microdata support as well but |
|
// only specified in the WHATWG spec document. See |
|
// https://html.spec.whatwg.org/multipage/microdata.html#microdata-dom-api |
|
itemID: 0, |
|
itemRef: 0, |
|
// results show looking glass icon and recent searches on input |
|
// search fields in WebKit/Blink |
|
results: 0, |
|
// IE-only attribute that specifies security restrictions on an iframe |
|
// as an alternative to the sandbox attribute on IE<10 |
|
security: 0, |
|
// IE-only attribute that controls focus behavior |
|
unselectable: 0 |
|
}, |
|
DOMAttributeNames: { |
|
acceptCharset: 'accept-charset', |
|
className: 'class', |
|
htmlFor: 'for', |
|
httpEquiv: 'http-equiv' |
|
}, |
|
DOMPropertyNames: {} |
|
}; |
|
|
|
module.exports = HTMLDOMPropertyConfig; |
|
},{"11":11}],23:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
/** |
|
* Escape and wrap key so it is safe to use as a reactid |
|
* |
|
* @param {string} key to be escaped. |
|
* @return {string} the escaped key. |
|
*/ |
|
|
|
function escape(key) { |
|
var escapeRegex = /[=:]/g; |
|
var escaperLookup = { |
|
'=': '=0', |
|
':': '=2' |
|
}; |
|
var escapedString = ('' + key).replace(escapeRegex, function (match) { |
|
return escaperLookup[match]; |
|
}); |
|
|
|
return '$' + escapedString; |
|
} |
|
|
|
/** |
|
* Unescape and unwrap key for human-readable display |
|
* |
|
* @param {string} key to unescape. |
|
* @return {string} the unescaped key. |
|
*/ |
|
function unescape(key) { |
|
var unescapeRegex = /(=0|=2)/g; |
|
var unescaperLookup = { |
|
'=0': '=', |
|
'=2': ':' |
|
}; |
|
var keySubstring = key[0] === '.' && key[1] === '$' ? key.substring(2) : key.substring(1); |
|
|
|
return ('' + keySubstring).replace(unescapeRegex, function (match) { |
|
return unescaperLookup[match]; |
|
}); |
|
} |
|
|
|
var KeyEscapeUtils = { |
|
escape: escape, |
|
unescape: unescape |
|
}; |
|
|
|
module.exports = KeyEscapeUtils; |
|
},{}],24:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125); |
|
|
|
var React = _dereq_(134); |
|
var ReactPropTypesSecret = _dereq_(73); |
|
|
|
var invariant = _dereq_(150); |
|
var warning = _dereq_(157); |
|
|
|
var hasReadOnlyValue = { |
|
'button': true, |
|
'checkbox': true, |
|
'image': true, |
|
'hidden': true, |
|
'radio': true, |
|
'reset': true, |
|
'submit': true |
|
}; |
|
|
|
function _assertSingleLink(inputProps) { |
|
!(inputProps.checkedLink == null || inputProps.valueLink == null) ? "development" !== 'production' ? invariant(false, 'Cannot provide a checkedLink and a valueLink. If you want to use checkedLink, you probably don\'t want to use valueLink and vice versa.') : _prodInvariant('87') : void 0; |
|
} |
|
function _assertValueLink(inputProps) { |
|
_assertSingleLink(inputProps); |
|
!(inputProps.value == null && inputProps.onChange == null) ? "development" !== 'production' ? invariant(false, '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.') : _prodInvariant('88') : void 0; |
|
} |
|
|
|
function _assertCheckedLink(inputProps) { |
|
_assertSingleLink(inputProps); |
|
!(inputProps.checked == null && inputProps.onChange == null) ? "development" !== 'production' ? invariant(false, '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') : _prodInvariant('89') : void 0; |
|
} |
|
|
|
var propTypes = { |
|
value: function (props, propName, componentName) { |
|
if (!props[propName] || hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled) { |
|
return null; |
|
} |
|
return new Error('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`.'); |
|
}, |
|
checked: function (props, propName, componentName) { |
|
if (!props[propName] || props.onChange || props.readOnly || props.disabled) { |
|
return null; |
|
} |
|
return new Error('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`.'); |
|
}, |
|
onChange: React.PropTypes.func |
|
}; |
|
|
|
var loggedTypeFailures = {}; |
|
function getDeclarationErrorAddendum(owner) { |
|
if (owner) { |
|
var name = owner.getName(); |
|
if (name) { |
|
return ' Check the render method of `' + name + '`.'; |
|
} |
|
} |
|
return ''; |
|
} |
|
|
|
/** |
|
* Provide a linked `value` attribute for controlled forms. You should not use |
|
* this outside of the ReactDOM controlled form components. |
|
*/ |
|
var LinkedValueUtils = { |
|
checkPropTypes: function (tagName, props, owner) { |
|
for (var propName in propTypes) { |
|
if (propTypes.hasOwnProperty(propName)) { |
|
var error = propTypes[propName](props, propName, tagName, 'prop', null, ReactPropTypesSecret); |
|
} |
|
if (error instanceof Error && !(error.message in loggedTypeFailures)) { |
|
// Only monitor this failure once because there tends to be a lot of the |
|
// same error. |
|
loggedTypeFailures[error.message] = true; |
|
|
|
var addendum = getDeclarationErrorAddendum(owner); |
|
"development" !== 'production' ? warning(false, 'Failed form propType: %s%s', error.message, addendum) : void 0; |
|
} |
|
} |
|
}, |
|
|
|
/** |
|
* @param {object} inputProps Props for form component |
|
* @return {*} current value of the input either from value prop or link. |
|
*/ |
|
getValue: function (inputProps) { |
|
if (inputProps.valueLink) { |
|
_assertValueLink(inputProps); |
|
return inputProps.valueLink.value; |
|
} |
|
return inputProps.value; |
|
}, |
|
|
|
/** |
|
* @param {object} inputProps Props for form component |
|
* @return {*} current checked status of the input either from checked prop |
|
* or link. |
|
*/ |
|
getChecked: function (inputProps) { |
|
if (inputProps.checkedLink) { |
|
_assertCheckedLink(inputProps); |
|
return inputProps.checkedLink.value; |
|
} |
|
return inputProps.checked; |
|
}, |
|
|
|
/** |
|
* @param {object} inputProps Props for form component |
|
* @param {SyntheticEvent} event change event to handle |
|
*/ |
|
executeOnChange: function (inputProps, event) { |
|
if (inputProps.valueLink) { |
|
_assertValueLink(inputProps); |
|
return inputProps.valueLink.requestChange(event.target.value); |
|
} else if (inputProps.checkedLink) { |
|
_assertCheckedLink(inputProps); |
|
return inputProps.checkedLink.requestChange(event.target.checked); |
|
} else if (inputProps.onChange) { |
|
return inputProps.onChange.call(undefined, event); |
|
} |
|
} |
|
}; |
|
|
|
module.exports = LinkedValueUtils; |
|
},{"125":125,"134":134,"150":150,"157":157,"73":73}],25:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125); |
|
|
|
var invariant = _dereq_(150); |
|
|
|
/** |
|
* 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 fourArgumentPooler = function (a1, a2, a3, a4) { |
|
var Klass = this; |
|
if (Klass.instancePool.length) { |
|
var instance = Klass.instancePool.pop(); |
|
Klass.call(instance, a1, a2, a3, a4); |
|
return instance; |
|
} else { |
|
return new Klass(a1, a2, a3, a4); |
|
} |
|
}; |
|
|
|
var standardReleaser = function (instance) { |
|
var Klass = this; |
|
!(instance instanceof Klass) ? "development" !== 'production' ? invariant(false, 'Trying to release an instance into a pool of a different type.') : _prodInvariant('25') : void 0; |
|
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. |
|
* |
|
* @param {Function} CopyConstructor Constructor that can be used to reset. |
|
* @param {Function} pooler Customizable pooler. |
|
*/ |
|
var addPoolingTo = function (CopyConstructor, pooler) { |
|
// Casting as any so that flow ignores the actual implementation and trusts |
|
// it to match the type we declared |
|
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, |
|
fourArgumentPooler: fourArgumentPooler |
|
}; |
|
|
|
module.exports = PooledClass; |
|
},{"125":125,"150":150}],26:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _assign = _dereq_(158); |
|
|
|
var EventPluginRegistry = _dereq_(18); |
|
var ReactEventEmitterMixin = _dereq_(56); |
|
var ViewportMetrics = _dereq_(101); |
|
|
|
var getVendorPrefixedEventName = _dereq_(120); |
|
var isEventSupported = _dereq_(122); |
|
|
|
/** |
|
* Summary of `ReactBrowserEventEmitter` event handling: |
|
* |
|
* - Top-level delegation is used to trap most native browser events. This |
|
* may only occur in the main thread and is the responsibility of |
|
* ReactEventListener, which is injected and can therefore support pluggable |
|
* event sources. This is the only work that occurs in the main thread. |
|
* |
|
* - We normalize and de-duplicate events to account for browser quirks. This |
|
* may be done in the worker thread. |
|
* |
|
* - 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 | . |
|
* +------------+ . |
|
* | . |
|
* v . |
|
* +------------+ . |
|
* | ReactEvent | . |
|
* | Listener | . |
|
* +------------+ . +-----------+ |
|
* | . +--------+|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 hasEventPageXY; |
|
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 = { |
|
topAbort: 'abort', |
|
topAnimationEnd: getVendorPrefixedEventName('animationend') || 'animationend', |
|
topAnimationIteration: getVendorPrefixedEventName('animationiteration') || 'animationiteration', |
|
topAnimationStart: getVendorPrefixedEventName('animationstart') || 'animationstart', |
|
topBlur: 'blur', |
|
topCanPlay: 'canplay', |
|
topCanPlayThrough: 'canplaythrough', |
|
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', |
|
topDurationChange: 'durationchange', |
|
topEmptied: 'emptied', |
|
topEncrypted: 'encrypted', |
|
topEnded: 'ended', |
|
topError: 'error', |
|
topFocus: 'focus', |
|
topInput: 'input', |
|
topKeyDown: 'keydown', |
|
topKeyPress: 'keypress', |
|
topKeyUp: 'keyup', |
|
topLoadedData: 'loadeddata', |
|
topLoadedMetadata: 'loadedmetadata', |
|
topLoadStart: 'loadstart', |
|
topMouseDown: 'mousedown', |
|
topMouseMove: 'mousemove', |
|
topMouseOut: 'mouseout', |
|
topMouseOver: 'mouseover', |
|
topMouseUp: 'mouseup', |
|
topPaste: 'paste', |
|
topPause: 'pause', |
|
topPlay: 'play', |
|
topPlaying: 'playing', |
|
topProgress: 'progress', |
|
topRateChange: 'ratechange', |
|
topScroll: 'scroll', |
|
topSeeked: 'seeked', |
|
topSeeking: 'seeking', |
|
topSelectionChange: 'selectionchange', |
|
topStalled: 'stalled', |
|
topSuspend: 'suspend', |
|
topTextInput: 'textInput', |
|
topTimeUpdate: 'timeupdate', |
|
topTouchCancel: 'touchcancel', |
|
topTouchEnd: 'touchend', |
|
topTouchMove: 'touchmove', |
|
topTouchStart: 'touchstart', |
|
topTransitionEnd: getVendorPrefixedEventName('transitionend') || 'transitionend', |
|
topVolumeChange: 'volumechange', |
|
topWaiting: 'waiting', |
|
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) { |
|
// In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty` |
|
// directly. |
|
if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) { |
|
mountAt[topListenersIDKey] = reactTopListenersCounter++; |
|
alreadyListeningTo[mountAt[topListenersIDKey]] = {}; |
|
} |
|
return alreadyListeningTo[mountAt[topListenersIDKey]]; |
|
} |
|
|
|
/** |
|
* `ReactBrowserEventEmitter` is used to attach top-level event listeners. For |
|
* example: |
|
* |
|
* EventPluginHub.putListener('myID', 'onClick', myFunction); |
|
* |
|
* This would allocate a "registration" of `('onClick', myFunction)` on 'myID'. |
|
* |
|
* @internal |
|
*/ |
|
var ReactBrowserEventEmitter = _assign({}, ReactEventEmitterMixin, { |
|
|
|
/** |
|
* Injectable event backend |
|
*/ |
|
ReactEventListener: null, |
|
|
|
injection: { |
|
/** |
|
* @param {object} ReactEventListener |
|
*/ |
|
injectReactEventListener: function (ReactEventListener) { |
|
ReactEventListener.setHandleTopLevel(ReactBrowserEventEmitter.handleTopLevel); |
|
ReactBrowserEventEmitter.ReactEventListener = ReactEventListener; |
|
} |
|
}, |
|
|
|
/** |
|
* Sets whether or not any created callbacks should be enabled. |
|
* |
|
* @param {boolean} enabled True if callbacks should be enabled. |
|
*/ |
|
setEnabled: function (enabled) { |
|
if (ReactBrowserEventEmitter.ReactEventListener) { |
|
ReactBrowserEventEmitter.ReactEventListener.setEnabled(enabled); |
|
} |
|
}, |
|
|
|
/** |
|
* @return {boolean} True if callbacks are enabled. |
|
*/ |
|
isEnabled: function () { |
|
return !!(ReactBrowserEventEmitter.ReactEventListener && ReactBrowserEventEmitter.ReactEventListener.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 {object} contentDocumentHandle Document which owns the container |
|
*/ |
|
listenTo: function (registrationName, contentDocumentHandle) { |
|
var mountAt = contentDocumentHandle; |
|
var isListening = getListeningForDocument(mountAt); |
|
var dependencies = EventPluginRegistry.registrationNameDependencies[registrationName]; |
|
|
|
for (var i = 0; i < dependencies.length; i++) { |
|
var dependency = dependencies[i]; |
|
if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) { |
|
if (dependency === 'topWheel') { |
|
if (isEventSupported('wheel')) { |
|
ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topWheel', 'wheel', mountAt); |
|
} else if (isEventSupported('mousewheel')) { |
|
ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topWheel', 'mousewheel', mountAt); |
|
} else { |
|
// Firefox needs to capture a different mouse scroll event. |
|
// @see http://www.quirksmode.org/dom/events/tests/scroll.html |
|
ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topWheel', 'DOMMouseScroll', mountAt); |
|
} |
|
} else if (dependency === 'topScroll') { |
|
|
|
if (isEventSupported('scroll', true)) { |
|
ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent('topScroll', 'scroll', mountAt); |
|
} else { |
|
ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topScroll', 'scroll', ReactBrowserEventEmitter.ReactEventListener.WINDOW_HANDLE); |
|
} |
|
} else if (dependency === 'topFocus' || dependency === 'topBlur') { |
|
|
|
if (isEventSupported('focus', true)) { |
|
ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent('topFocus', 'focus', mountAt); |
|
ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent('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 |
|
ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topFocus', 'focusin', mountAt); |
|
ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topBlur', 'focusout', mountAt); |
|
} |
|
|
|
// to make sure blur and focus event listeners are only attached once |
|
isListening.topBlur = true; |
|
isListening.topFocus = true; |
|
} else if (topEventMapping.hasOwnProperty(dependency)) { |
|
ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(dependency, topEventMapping[dependency], mountAt); |
|
} |
|
|
|
isListening[dependency] = true; |
|
} |
|
} |
|
}, |
|
|
|
trapBubbledEvent: function (topLevelType, handlerBaseName, handle) { |
|
return ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelType, handlerBaseName, handle); |
|
}, |
|
|
|
trapCapturedEvent: function (topLevelType, handlerBaseName, handle) { |
|
return ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(topLevelType, handlerBaseName, handle); |
|
}, |
|
|
|
/** |
|
* Protect against document.createEvent() returning null |
|
* Some popup blocker extensions appear to do this: |
|
* https://github.com/facebook/react/issues/6887 |
|
*/ |
|
supportsEventPageXY: function () { |
|
if (!document.createEvent) { |
|
return false; |
|
} |
|
var ev = document.createEvent('MouseEvent'); |
|
return ev != null && 'pageX' in ev; |
|
}, |
|
|
|
/** |
|
* Listens to window scroll and resize events. We cache scroll values so that |
|
* application code can access them without triggering reflows. |
|
* |
|
* ViewportMetrics is only used by SyntheticMouse/TouchEvent and only when |
|
* pageX/pageY isn't supported (legacy browsers). |
|
* |
|
* NOTE: Scroll events do not bubble. |
|
* |
|
* @see http://www.quirksmode.org/dom/events/scroll.html |
|
*/ |
|
ensureScrollValueMonitoring: function () { |
|
if (hasEventPageXY === undefined) { |
|
hasEventPageXY = ReactBrowserEventEmitter.supportsEventPageXY(); |
|
} |
|
if (!hasEventPageXY && !isMonitoringScrollValue) { |
|
var refresh = ViewportMetrics.refreshScrollValues; |
|
ReactBrowserEventEmitter.ReactEventListener.monitorScrollValue(refresh); |
|
isMonitoringScrollValue = true; |
|
} |
|
} |
|
|
|
}); |
|
|
|
module.exports = ReactBrowserEventEmitter; |
|
},{"101":101,"120":120,"122":122,"158":158,"18":18,"56":56}],27:[function(_dereq_,module,exports){ |
|
(function (process){ |
|
/** |
|
* Copyright 2014-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var ReactReconciler = _dereq_(75); |
|
|
|
var instantiateReactComponent = _dereq_(121); |
|
var KeyEscapeUtils = _dereq_(23); |
|
var shouldUpdateReactComponent = _dereq_(129); |
|
var traverseAllChildren = _dereq_(130); |
|
var warning = _dereq_(157); |
|
|
|
var ReactComponentTreeHook; |
|
|
|
if (typeof process !== 'undefined' && process.env && "development" === 'test') { |
|
// Temporary hack. |
|
// Inline requires don't work well with Jest: |
|
// https://github.com/facebook/react/issues/7240 |
|
// Remove the inline requires when we don't need them anymore: |
|
// https://github.com/facebook/react/pull/7178 |
|
ReactComponentTreeHook = _dereq_(132); |
|
} |
|
|
|
function instantiateChild(childInstances, child, name, selfDebugID) { |
|
// We found a component instance. |
|
var keyUnique = childInstances[name] === undefined; |
|
if ("development" !== 'production') { |
|
if (!ReactComponentTreeHook) { |
|
ReactComponentTreeHook = _dereq_(132); |
|
} |
|
if (!keyUnique) { |
|
"development" !== 'production' ? warning(false, 'flattenChildren(...): Encountered two children with the same key, ' + '`%s`. Child keys must be unique; when two children share a key, only ' + 'the first child will be used.%s', KeyEscapeUtils.unescape(name), ReactComponentTreeHook.getStackAddendumByID(selfDebugID)) : void 0; |
|
} |
|
} |
|
if (child != null && keyUnique) { |
|
childInstances[name] = instantiateReactComponent(child, true); |
|
} |
|
} |
|
|
|
/** |
|
* ReactChildReconciler provides helpers for initializing or updating a set of |
|
* children. Its output is suitable for passing it onto ReactMultiChild which |
|
* does diffed reordering and insertion. |
|
*/ |
|
var ReactChildReconciler = { |
|
/** |
|
* 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} nestedChildNodes Nested child maps. |
|
* @return {?object} A set of child instances. |
|
* @internal |
|
*/ |
|
instantiateChildren: function (nestedChildNodes, transaction, context, selfDebugID // 0 in production and for roots |
|
) { |
|
if (nestedChildNodes == null) { |
|
return null; |
|
} |
|
var childInstances = {}; |
|
|
|
if ("development" !== 'production') { |
|
traverseAllChildren(nestedChildNodes, function (childInsts, child, name) { |
|
return instantiateChild(childInsts, child, name, selfDebugID); |
|
}, childInstances); |
|
} else { |
|
traverseAllChildren(nestedChildNodes, instantiateChild, childInstances); |
|
} |
|
return childInstances; |
|
}, |
|
|
|
/** |
|
* Updates the rendered children and returns a new set of children. |
|
* |
|
* @param {?object} prevChildren Previously initialized set of children. |
|
* @param {?object} nextChildren Flat child element maps. |
|
* @param {ReactReconcileTransaction} transaction |
|
* @param {object} context |
|
* @return {?object} A new set of child instances. |
|
* @internal |
|
*/ |
|
updateChildren: function (prevChildren, nextChildren, mountImages, removedNodes, transaction, hostParent, hostContainerInfo, context, selfDebugID // 0 in production and for roots |
|
) { |
|
// We currently don't have a way to track moves here but if we use iterators |
|
// instead of for..in we can zip the iterators and check if an item has |
|
// moved. |
|
// TODO: If nothing has changed, return the prevChildren object so that we |
|
// can quickly bailout if nothing has changed. |
|
if (!nextChildren && !prevChildren) { |
|
return; |
|
} |
|
var name; |
|
var prevChild; |
|
for (name in nextChildren) { |
|
if (!nextChildren.hasOwnProperty(name)) { |
|
continue; |
|
} |
|
prevChild = prevChildren && prevChildren[name]; |
|
var prevElement = prevChild && prevChild._currentElement; |
|
var nextElement = nextChildren[name]; |
|
if (prevChild != null && shouldUpdateReactComponent(prevElement, nextElement)) { |
|
ReactReconciler.receiveComponent(prevChild, nextElement, transaction, context); |
|
nextChildren[name] = prevChild; |
|
} else { |
|
if (prevChild) { |
|
removedNodes[name] = ReactReconciler.getHostNode(prevChild); |
|
ReactReconciler.unmountComponent(prevChild, false); |
|
} |
|
// The child must be instantiated before it's mounted. |
|
var nextChildInstance = instantiateReactComponent(nextElement, true); |
|
nextChildren[name] = nextChildInstance; |
|
// Creating mount image now ensures refs are resolved in right order |
|
// (see https://github.com/facebook/react/pull/7101 for explanation). |
|
var nextChildMountImage = ReactReconciler.mountComponent(nextChildInstance, transaction, hostParent, hostContainerInfo, context, selfDebugID); |
|
mountImages.push(nextChildMountImage); |
|
} |
|
} |
|
// Unmount children that are no longer present. |
|
for (name in prevChildren) { |
|
if (prevChildren.hasOwnProperty(name) && !(nextChildren && nextChildren.hasOwnProperty(name))) { |
|
prevChild = prevChildren[name]; |
|
removedNodes[name] = ReactReconciler.getHostNode(prevChild); |
|
ReactReconciler.unmountComponent(prevChild, false); |
|
} |
|
} |
|
}, |
|
|
|
/** |
|
* Unmounts all rendered children. This should be used to clean up children |
|
* when this component is unmounted. |
|
* |
|
* @param {?object} renderedChildren Previously initialized set of children. |
|
* @internal |
|
*/ |
|
unmountChildren: function (renderedChildren, safely) { |
|
for (var name in renderedChildren) { |
|
if (renderedChildren.hasOwnProperty(name)) { |
|
var renderedChild = renderedChildren[name]; |
|
ReactReconciler.unmountComponent(renderedChild, safely); |
|
} |
|
} |
|
} |
|
|
|
}; |
|
|
|
module.exports = ReactChildReconciler; |
|
}).call(this,undefined) |
|
},{"121":121,"129":129,"130":130,"132":132,"157":157,"23":23,"75":75}],28:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var DOMChildrenOperations = _dereq_(8); |
|
var ReactDOMIDOperations = _dereq_(38); |
|
|
|
/** |
|
* Abstracts away all functionality of the reconciler that requires knowledge of |
|
* the browser context. TODO: These callers should be refactored to avoid the |
|
* need for this injection. |
|
*/ |
|
var ReactComponentBrowserEnvironment = { |
|
|
|
processChildrenUpdates: ReactDOMIDOperations.dangerouslyProcessChildrenUpdates, |
|
|
|
replaceNodeWithMarkup: DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup |
|
|
|
}; |
|
|
|
module.exports = ReactComponentBrowserEnvironment; |
|
},{"38":38,"8":8}],29:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2014-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125); |
|
|
|
var invariant = _dereq_(150); |
|
|
|
var injected = false; |
|
|
|
var ReactComponentEnvironment = { |
|
|
|
/** |
|
* Optionally injectable hook for swapping out mount images in the middle of |
|
* the tree. |
|
*/ |
|
replaceNodeWithMarkup: null, |
|
|
|
/** |
|
* Optionally injectable hook for processing a queue of child updates. Will |
|
* later move into MultiChildComponents. |
|
*/ |
|
processChildrenUpdates: null, |
|
|
|
injection: { |
|
injectEnvironment: function (environment) { |
|
!!injected ? "development" !== 'production' ? invariant(false, 'ReactCompositeComponent: injectEnvironment() can only be called once.') : _prodInvariant('104') : void 0; |
|
ReactComponentEnvironment.replaceNodeWithMarkup = environment.replaceNodeWithMarkup; |
|
ReactComponentEnvironment.processChildrenUpdates = environment.processChildrenUpdates; |
|
injected = true; |
|
} |
|
} |
|
|
|
}; |
|
|
|
module.exports = ReactComponentEnvironment; |
|
},{"125":125,"150":150}],30:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125), |
|
_assign = _dereq_(158); |
|
|
|
var React = _dereq_(134); |
|
var ReactComponentEnvironment = _dereq_(29); |
|
var ReactCurrentOwner = _dereq_(133); |
|
var ReactErrorUtils = _dereq_(55); |
|
var ReactInstanceMap = _dereq_(63); |
|
var ReactInstrumentation = _dereq_(64); |
|
var ReactNodeTypes = _dereq_(69); |
|
var ReactReconciler = _dereq_(75); |
|
|
|
if ("development" !== 'production') { |
|
var checkReactTypeSpec = _dereq_(104); |
|
} |
|
|
|
var emptyObject = _dereq_(143); |
|
var invariant = _dereq_(150); |
|
var shallowEqual = _dereq_(156); |
|
var shouldUpdateReactComponent = _dereq_(129); |
|
var warning = _dereq_(157); |
|
|
|
var CompositeTypes = { |
|
ImpureClass: 0, |
|
PureClass: 1, |
|
StatelessFunctional: 2 |
|
}; |
|
|
|
function StatelessComponent(Component) {} |
|
StatelessComponent.prototype.render = function () { |
|
var Component = ReactInstanceMap.get(this)._currentElement.type; |
|
var element = Component(this.props, this.context, this.updater); |
|
warnIfInvalidElement(Component, element); |
|
return element; |
|
}; |
|
|
|
function warnIfInvalidElement(Component, element) { |
|
if ("development" !== 'production') { |
|
"development" !== 'production' ? warning(element === null || element === false || React.isValidElement(element), '%s(...): A valid React element (or null) must be returned. You may have ' + 'returned undefined, an array or some other invalid object.', Component.displayName || Component.name || 'Component') : void 0; |
|
"development" !== 'production' ? warning(!Component.childContextTypes, '%s(...): childContextTypes cannot be defined on a functional component.', Component.displayName || Component.name || 'Component') : void 0; |
|
} |
|
} |
|
|
|
function shouldConstruct(Component) { |
|
return !!(Component.prototype && Component.prototype.isReactComponent); |
|
} |
|
|
|
function isPureComponent(Component) { |
|
return !!(Component.prototype && Component.prototype.isPureReactComponent); |
|
} |
|
|
|
// Separated into a function to contain deoptimizations caused by try/finally. |
|
function measureLifeCyclePerf(fn, debugID, timerType) { |
|
if (debugID === 0) { |
|
// Top-level wrappers (see ReactMount) and empty components (see |
|
// ReactDOMEmptyComponent) are invisible to hooks and devtools. |
|
// Both are implementation details that should go away in the future. |
|
return fn(); |
|
} |
|
|
|
ReactInstrumentation.debugTool.onBeginLifeCycleTimer(debugID, timerType); |
|
try { |
|
return fn(); |
|
} finally { |
|
ReactInstrumentation.debugTool.onEndLifeCycleTimer(debugID, timerType); |
|
} |
|
} |
|
|
|
/** |
|
* ------------------ The Life-Cycle of a Composite Component ------------------ |
|
* |
|
* - constructor: Initialization of state. The instance is now retained. |
|
* - componentWillMount |
|
* - render |
|
* - [children's constructors] |
|
* - [children's componentWillMount and render] |
|
* - [children's componentDidMount] |
|
* - componentDidMount |
|
* |
|
* Update Phases: |
|
* - componentWillReceiveProps (only called if parent updated) |
|
* - shouldComponentUpdate |
|
* - componentWillUpdate |
|
* - render |
|
* - [children's constructors or receive props phases] |
|
* - componentDidUpdate |
|
* |
|
* - componentWillUnmount |
|
* - [children's componentWillUnmount] |
|
* - [children destroyed] |
|
* - (destroyed): The instance is now blank, released by React and ready for GC. |
|
* |
|
* ----------------------------------------------------------------------------- |
|
*/ |
|
|
|
/** |
|
* An incrementing ID assigned to each component when it is mounted. This is |
|
* used to enforce the order in which `ReactUpdates` updates dirty components. |
|
* |
|
* @private |
|
*/ |
|
var nextMountID = 1; |
|
|
|
/** |
|
* @lends {ReactCompositeComponent.prototype} |
|
*/ |
|
var ReactCompositeComponent = { |
|
|
|
/** |
|
* Base constructor for all composite component. |
|
* |
|
* @param {ReactElement} element |
|
* @final |
|
* @internal |
|
*/ |
|
construct: function (element) { |
|
this._currentElement = element; |
|
this._rootNodeID = 0; |
|
this._compositeType = null; |
|
this._instance = null; |
|
this._hostParent = null; |
|
this._hostContainerInfo = null; |
|
|
|
// See ReactUpdateQueue |
|
this._updateBatchNumber = null; |
|
this._pendingElement = null; |
|
this._pendingStateQueue = null; |
|
this._pendingReplaceState = false; |
|
this._pendingForceUpdate = false; |
|
|
|
this._renderedNodeType = null; |
|
this._renderedComponent = null; |
|
this._context = null; |
|
this._mountOrder = 0; |
|
this._topLevelWrapper = null; |
|
|
|
// See ReactUpdates and ReactUpdateQueue. |
|
this._pendingCallbacks = null; |
|
|
|
// ComponentWillUnmount shall only be called once |
|
this._calledComponentWillUnmount = false; |
|
|
|
if ("development" !== 'production') { |
|
this._warnedAboutRefsInRender = false; |
|
} |
|
}, |
|
|
|
/** |
|
* Initializes the component, renders markup, and registers event listeners. |
|
* |
|
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction |
|
* @param {?object} hostParent |
|
* @param {?object} hostContainerInfo |
|
* @param {?object} context |
|
* @return {?string} Rendered markup to be inserted into the DOM. |
|
* @final |
|
* @internal |
|
*/ |
|
mountComponent: function (transaction, hostParent, hostContainerInfo, context) { |
|
var _this = this; |
|
|
|
this._context = context; |
|
this._mountOrder = nextMountID++; |
|
this._hostParent = hostParent; |
|
this._hostContainerInfo = hostContainerInfo; |
|
|
|
var publicProps = this._currentElement.props; |
|
var publicContext = this._processContext(context); |
|
|
|
var Component = this._currentElement.type; |
|
|
|
var updateQueue = transaction.getUpdateQueue(); |
|
|
|
// Initialize the public class |
|
var doConstruct = shouldConstruct(Component); |
|
var inst = this._constructComponent(doConstruct, publicProps, publicContext, updateQueue); |
|
var renderedElement; |
|
|
|
// Support functional components |
|
if (!doConstruct && (inst == null || inst.render == null)) { |
|
renderedElement = inst; |
|
warnIfInvalidElement(Component, renderedElement); |
|
!(inst === null || inst === false || React.isValidElement(inst)) ? "development" !== 'production' ? invariant(false, '%s(...): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.', Component.displayName || Component.name || 'Component') : _prodInvariant('105', Component.displayName || Component.name || 'Component') : void 0; |
|
inst = new StatelessComponent(Component); |
|
this._compositeType = CompositeTypes.StatelessFunctional; |
|
} else { |
|
if (isPureComponent(Component)) { |
|
this._compositeType = CompositeTypes.PureClass; |
|
} else { |
|
this._compositeType = CompositeTypes.ImpureClass; |
|
} |
|
} |
|
|
|
if ("development" !== 'production') { |
|
// This will throw later in _renderValidatedComponent, but add an early |
|
// warning now to help debugging |
|
if (inst.render == null) { |
|
"development" !== 'production' ? warning(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', Component.displayName || Component.name || 'Component') : void 0; |
|
} |
|
|
|
var propsMutated = inst.props !== publicProps; |
|
var componentName = Component.displayName || Component.name || 'Component'; |
|
|
|
"development" !== 'production' ? warning(inst.props === undefined || !propsMutated, '%s(...): When calling super() in `%s`, make sure to pass ' + 'up the same props that your component\'s constructor was passed.', componentName, componentName) : void 0; |
|
} |
|
|
|
// These should be set up in the constructor, but as a convenience for |
|
// simpler class abstractions, we set them up after the fact. |
|
inst.props = publicProps; |
|
inst.context = publicContext; |
|
inst.refs = emptyObject; |
|
inst.updater = updateQueue; |
|
|
|
this._instance = inst; |
|
|
|
// Store a reference from the instance back to the internal representation |
|
ReactInstanceMap.set(inst, this); |
|
|
|
if ("development" !== 'production') { |
|
// Since plain JS classes are defined without any special initialization |
|
// logic, we can not catch common errors early. Therefore, we have to |
|
// catch them here, at initialization time, instead. |
|
"development" !== 'production' ? warning(!inst.getInitialState || inst.getInitialState.isReactClassApproved || inst.state, 'getInitialState was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Did you mean to define a state property instead?', this.getName() || 'a component') : void 0; |
|
"development" !== 'production' ? warning(!inst.getDefaultProps || inst.getDefaultProps.isReactClassApproved, 'getDefaultProps was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Use a static property to define defaultProps instead.', this.getName() || 'a component') : void 0; |
|
"development" !== 'production' ? warning(!inst.propTypes, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', this.getName() || 'a component') : void 0; |
|
"development" !== 'production' ? warning(!inst.contextTypes, 'contextTypes was defined as an instance property on %s. Use a ' + 'static property to define contextTypes instead.', this.getName() || 'a component') : void 0; |
|
"development" !== 'production' ? warning(typeof inst.componentShouldUpdate !== 'function', '%s 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.', this.getName() || 'A component') : void 0; |
|
"development" !== 'production' ? warning(typeof inst.componentDidUnmount !== 'function', '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', this.getName() || 'A component') : void 0; |
|
"development" !== 'production' ? warning(typeof inst.componentWillRecieveProps !== 'function', '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', this.getName() || 'A component') : void 0; |
|
} |
|
|
|
var initialState = inst.state; |
|
if (initialState === undefined) { |
|
inst.state = initialState = null; |
|
} |
|
!(typeof initialState === 'object' && !Array.isArray(initialState)) ? "development" !== 'production' ? invariant(false, '%s.state: must be set to an object or null', this.getName() || 'ReactCompositeComponent') : _prodInvariant('106', this.getName() || 'ReactCompositeComponent') : void 0; |
|
|
|
this._pendingStateQueue = null; |
|
this._pendingReplaceState = false; |
|
this._pendingForceUpdate = false; |
|
|
|
var markup; |
|
if (inst.unstable_handleError) { |
|
markup = this.performInitialMountWithErrorHandling(renderedElement, hostParent, hostContainerInfo, transaction, context); |
|
} else { |
|
markup = this.performInitialMount(renderedElement, hostParent, hostContainerInfo, transaction, context); |
|
} |
|
|
|
if (inst.componentDidMount) { |
|
if ("development" !== 'production') { |
|
transaction.getReactMountReady().enqueue(function () { |
|
measureLifeCyclePerf(function () { |
|
return inst.componentDidMount(); |
|
}, _this._debugID, 'componentDidMount'); |
|
}); |
|
} else { |
|
transaction.getReactMountReady().enqueue(inst.componentDidMount, inst); |
|
} |
|
} |
|
|
|
return markup; |
|
}, |
|
|
|
_constructComponent: function (doConstruct, publicProps, publicContext, updateQueue) { |
|
if ("development" !== 'production') { |
|
ReactCurrentOwner.current = this; |
|
try { |
|
return this._constructComponentWithoutOwner(doConstruct, publicProps, publicContext, updateQueue); |
|
} finally { |
|
ReactCurrentOwner.current = null; |
|
} |
|
} else { |
|
return this._constructComponentWithoutOwner(doConstruct, publicProps, publicContext, updateQueue); |
|
} |
|
}, |
|
|
|
_constructComponentWithoutOwner: function (doConstruct, publicProps, publicContext, updateQueue) { |
|
var Component = this._currentElement.type; |
|
|
|
if (doConstruct) { |
|
if ("development" !== 'production') { |
|
return measureLifeCyclePerf(function () { |
|
return new Component(publicProps, publicContext, updateQueue); |
|
}, this._debugID, 'ctor'); |
|
} else { |
|
return new Component(publicProps, publicContext, updateQueue); |
|
} |
|
} |
|
|
|
// This can still be an instance in case of factory components |
|
// but we'll count this as time spent rendering as the more common case. |
|
if ("development" !== 'production') { |
|
return measureLifeCyclePerf(function () { |
|
return Component(publicProps, publicContext, updateQueue); |
|
}, this._debugID, 'render'); |
|
} else { |
|
return Component(publicProps, publicContext, updateQueue); |
|
} |
|
}, |
|
|
|
performInitialMountWithErrorHandling: function (renderedElement, hostParent, hostContainerInfo, transaction, context) { |
|
var markup; |
|
var checkpoint = transaction.checkpoint(); |
|
try { |
|
markup = this.performInitialMount(renderedElement, hostParent, hostContainerInfo, transaction, context); |
|
} catch (e) { |
|
// Roll back to checkpoint, handle error (which may add items to the transaction), and take a new checkpoint |
|
transaction.rollback(checkpoint); |
|
this._instance.unstable_handleError(e); |
|
if (this._pendingStateQueue) { |
|
this._instance.state = this._processPendingState(this._instance.props, this._instance.context); |
|
} |
|
checkpoint = transaction.checkpoint(); |
|
|
|
this._renderedComponent.unmountComponent(true); |
|
transaction.rollback(checkpoint); |
|
|
|
// Try again - we've informed the component about the error, so they can render an error message this time. |
|
// If this throws again, the error will bubble up (and can be caught by a higher error boundary). |
|
markup = this.performInitialMount(renderedElement, hostParent, hostContainerInfo, transaction, context); |
|
} |
|
return markup; |
|
}, |
|
|
|
performInitialMount: function (renderedElement, hostParent, hostContainerInfo, transaction, context) { |
|
var inst = this._instance; |
|
|
|
var debugID = 0; |
|
if ("development" !== 'production') { |
|
debugID = this._debugID; |
|
} |
|
|
|
if (inst.componentWillMount) { |
|
if ("development" !== 'production') { |
|
measureLifeCyclePerf(function () { |
|
return inst.componentWillMount(); |
|
}, debugID, 'componentWillMount'); |
|
} else { |
|
inst.componentWillMount(); |
|
} |
|
// When mounting, calls to `setState` by `componentWillMount` will set |
|
// `this._pendingStateQueue` without triggering a re-render. |
|
if (this._pendingStateQueue) { |
|
inst.state = this._processPendingState(inst.props, inst.context); |
|
} |
|
} |
|
|
|
// If not a stateless component, we now render |
|
if (renderedElement === undefined) { |
|
renderedElement = this._renderValidatedComponent(); |
|
} |
|
|
|
var nodeType = ReactNodeTypes.getType(renderedElement); |
|
this._renderedNodeType = nodeType; |
|
var child = this._instantiateReactComponent(renderedElement, nodeType !== ReactNodeTypes.EMPTY /* shouldHaveDebugID */ |
|
); |
|
this._renderedComponent = child; |
|
|
|
var markup = ReactReconciler.mountComponent(child, transaction, hostParent, hostContainerInfo, this._processChildContext(context), debugID); |
|
|
|
if ("development" !== 'production') { |
|
if (debugID !== 0) { |
|
var childDebugIDs = child._debugID !== 0 ? [child._debugID] : []; |
|
ReactInstrumentation.debugTool.onSetChildren(debugID, childDebugIDs); |
|
} |
|
} |
|
|
|
return markup; |
|
}, |
|
|
|
getHostNode: function () { |
|
return ReactReconciler.getHostNode(this._renderedComponent); |
|
}, |
|
|
|
/** |
|
* Releases any resources allocated by `mountComponent`. |
|
* |
|
* @final |
|
* @internal |
|
*/ |
|
unmountComponent: function (safely) { |
|
if (!this._renderedComponent) { |
|
return; |
|
} |
|
|
|
var inst = this._instance; |
|
|
|
if (inst.componentWillUnmount && !inst._calledComponentWillUnmount) { |
|
inst._calledComponentWillUnmount = true; |
|
|
|
if (safely) { |
|
var name = this.getName() + '.componentWillUnmount()'; |
|
ReactErrorUtils.invokeGuardedCallback(name, inst.componentWillUnmount.bind(inst)); |
|
} else { |
|
if ("development" !== 'production') { |
|
measureLifeCyclePerf(function () { |
|
return inst.componentWillUnmount(); |
|
}, this._debugID, 'componentWillUnmount'); |
|
} else { |
|
inst.componentWillUnmount(); |
|
} |
|
} |
|
} |
|
|
|
if (this._renderedComponent) { |
|
ReactReconciler.unmountComponent(this._renderedComponent, safely); |
|
this._renderedNodeType = null; |
|
this._renderedComponent = null; |
|
this._instance = null; |
|
} |
|
|
|
// Reset pending fields |
|
// Even if this component is scheduled for another update in ReactUpdates, |
|
// it would still be ignored because these fields are reset. |
|
this._pendingStateQueue = null; |
|
this._pendingReplaceState = false; |
|
this._pendingForceUpdate = false; |
|
this._pendingCallbacks = null; |
|
this._pendingElement = null; |
|
|
|
// These fields do not really need to be reset since this object is no |
|
// longer accessible. |
|
this._context = null; |
|
this._rootNodeID = 0; |
|
this._topLevelWrapper = null; |
|
|
|
// Delete the reference from the instance to this internal representation |
|
// which allow the internals to be properly cleaned up even if the user |
|
// leaks a reference to the public instance. |
|
ReactInstanceMap.remove(inst); |
|
|
|
// Some existing components rely on inst.props even after they've been |
|
// destroyed (in event handlers). |
|
// TODO: inst.props = null; |
|
// TODO: inst.state = null; |
|
// TODO: inst.context = null; |
|
}, |
|
|
|
/** |
|
* Filters the context object to only contain keys specified in |
|
* `contextTypes` |
|
* |
|
* @param {object} context |
|
* @return {?object} |
|
* @private |
|
*/ |
|
_maskContext: function (context) { |
|
var Component = this._currentElement.type; |
|
var contextTypes = Component.contextTypes; |
|
if (!contextTypes) { |
|
return emptyObject; |
|
} |
|
var maskedContext = {}; |
|
for (var contextName in contextTypes) { |
|
maskedContext[contextName] = context[contextName]; |
|
} |
|
return maskedContext; |
|
}, |
|
|
|
/** |
|
* 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 = this._maskContext(context); |
|
if ("development" !== 'production') { |
|
var Component = this._currentElement.type; |
|
if (Component.contextTypes) { |
|
this._checkContextTypes(Component.contextTypes, maskedContext, 'context'); |
|
} |
|
} |
|
return maskedContext; |
|
}, |
|
|
|
/** |
|
* @param {object} currentContext |
|
* @return {object} |
|
* @private |
|
*/ |
|
_processChildContext: function (currentContext) { |
|
var Component = this._currentElement.type; |
|
var inst = this._instance; |
|
var childContext; |
|
|
|
if (inst.getChildContext) { |
|
if ("development" !== 'production') { |
|
ReactInstrumentation.debugTool.onBeginProcessingChildContext(); |
|
try { |
|
childContext = inst.getChildContext(); |
|
} finally { |
|
ReactInstrumentation.debugTool.onEndProcessingChildContext(); |
|
} |
|
} else { |
|
childContext = inst.getChildContext(); |
|
} |
|
} |
|
|
|
if (childContext) { |
|
!(typeof Component.childContextTypes === 'object') ? "development" !== 'production' ? invariant(false, '%s.getChildContext(): childContextTypes must be defined in order to use getChildContext().', this.getName() || 'ReactCompositeComponent') : _prodInvariant('107', this.getName() || 'ReactCompositeComponent') : void 0; |
|
if ("development" !== 'production') { |
|
this._checkContextTypes(Component.childContextTypes, childContext, 'childContext'); |
|
} |
|
for (var name in childContext) { |
|
!(name in Component.childContextTypes) ? "development" !== 'production' ? invariant(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', this.getName() || 'ReactCompositeComponent', name) : _prodInvariant('108', this.getName() || 'ReactCompositeComponent', name) : void 0; |
|
} |
|
return _assign({}, currentContext, childContext); |
|
} |
|
return currentContext; |
|
}, |
|
|
|
/** |
|
* Assert that the context types are valid |
|
* |
|
* @param {object} typeSpecs Map of context field to a ReactPropType |
|
* @param {object} values Runtime values that need to be type-checked |
|
* @param {string} location e.g. "prop", "context", "child context" |
|
* @private |
|
*/ |
|
_checkContextTypes: function (typeSpecs, values, location) { |
|
if ("development" !== 'production') { |
|
checkReactTypeSpec(typeSpecs, values, location, this.getName(), null, this._debugID); |
|
} |
|
}, |
|
|
|
receiveComponent: function (nextElement, transaction, nextContext) { |
|
var prevElement = this._currentElement; |
|
var prevContext = this._context; |
|
|
|
this._pendingElement = null; |
|
|
|
this.updateComponent(transaction, prevElement, nextElement, prevContext, nextContext); |
|
}, |
|
|
|
/** |
|
* If any of `_pendingElement`, `_pendingStateQueue`, or `_pendingForceUpdate` |
|
* is set, update the component. |
|
* |
|
* @param {ReactReconcileTransaction} transaction |
|
* @internal |
|
*/ |
|
performUpdateIfNecessary: function (transaction) { |
|
if (this._pendingElement != null) { |
|
ReactReconciler.receiveComponent(this, this._pendingElement, transaction, this._context); |
|
} else if (this._pendingStateQueue !== null || this._pendingForceUpdate) { |
|
this.updateComponent(transaction, this._currentElement, this._currentElement, this._context, this._context); |
|
} else { |
|
this._updateBatchNumber = null; |
|
} |
|
}, |
|
|
|
/** |
|
* Perform an update to a mounted component. The componentWillReceiveProps and |
|
* shouldComponentUpdate methods are called, then (assuming the update isn't |
|
* skipped) the remaining update lifecycle methods are called and the DOM |
|
* representation is updated. |
|
* |
|
* By default, this implements React's rendering and reconciliation algorithm. |
|
* Sophisticated clients may wish to override this. |
|
* |
|
* @param {ReactReconcileTransaction} transaction |
|
* @param {ReactElement} prevParentElement |
|
* @param {ReactElement} nextParentElement |
|
* @internal |
|
* @overridable |
|
*/ |
|
updateComponent: function (transaction, prevParentElement, nextParentElement, prevUnmaskedContext, nextUnmaskedContext) { |
|
var inst = this._instance; |
|
!(inst != null) ? "development" !== 'production' ? invariant(false, 'Attempted to update component `%s` that has already been unmounted (or failed to mount).', this.getName() || 'ReactCompositeComponent') : _prodInvariant('136', this.getName() || 'ReactCompositeComponent') : void 0; |
|
|
|
var willReceive = false; |
|
var nextContext; |
|
|
|
// Determine if the context has changed or not |
|
if (this._context === nextUnmaskedContext) { |
|
nextContext = inst.context; |
|
} else { |
|
nextContext = this._processContext(nextUnmaskedContext); |
|
willReceive = true; |
|
} |
|
|
|
var prevProps = prevParentElement.props; |
|
var nextProps = nextParentElement.props; |
|
|
|
// Not a simple state update but a props update |
|
if (prevParentElement !== nextParentElement) { |
|
willReceive = true; |
|
} |
|
|
|
// An update here will schedule an update but immediately set |
|
// _pendingStateQueue which will ensure that any state updates gets |
|
// immediately reconciled instead of waiting for the next batch. |
|
if (willReceive && inst.componentWillReceiveProps) { |
|
if ("development" !== 'production') { |
|
measureLifeCyclePerf(function () { |
|
return inst.componentWillReceiveProps(nextProps, nextContext); |
|
}, this._debugID, 'componentWillReceiveProps'); |
|
} else { |
|
inst.componentWillReceiveProps(nextProps, nextContext); |
|
} |
|
} |
|
|
|
var nextState = this._processPendingState(nextProps, nextContext); |
|
var shouldUpdate = true; |
|
|
|
if (!this._pendingForceUpdate) { |
|
if (inst.shouldComponentUpdate) { |
|
if ("development" !== 'production') { |
|
shouldUpdate = measureLifeCyclePerf(function () { |
|
return inst.shouldComponentUpdate(nextProps, nextState, nextContext); |
|
}, this._debugID, 'shouldComponentUpdate'); |
|
} else { |
|
shouldUpdate = inst.shouldComponentUpdate(nextProps, nextState, nextContext); |
|
} |
|
} else { |
|
if (this._compositeType === CompositeTypes.PureClass) { |
|
shouldUpdate = !shallowEqual(prevProps, nextProps) || !shallowEqual(inst.state, nextState); |
|
} |
|
} |
|
} |
|
|
|
if ("development" !== 'production') { |
|
"development" !== 'production' ? warning(shouldUpdate !== undefined, '%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', this.getName() || 'ReactCompositeComponent') : void 0; |
|
} |
|
|
|
this._updateBatchNumber = null; |
|
if (shouldUpdate) { |
|
this._pendingForceUpdate = false; |
|
// Will set `this.props`, `this.state` and `this.context`. |
|
this._performComponentUpdate(nextParentElement, nextProps, nextState, nextContext, transaction, nextUnmaskedContext); |
|
} else { |
|
// If it's determined that a component should not update, we still want |
|
// to set props and state but we shortcut the rest of the update. |
|
this._currentElement = nextParentElement; |
|
this._context = nextUnmaskedContext; |
|
inst.props = nextProps; |
|
inst.state = nextState; |
|
inst.context = nextContext; |
|
} |
|
}, |
|
|
|
_processPendingState: function (props, context) { |
|
var inst = this._instance; |
|
var queue = this._pendingStateQueue; |
|
var replace = this._pendingReplaceState; |
|
this._pendingReplaceState = false; |
|
this._pendingStateQueue = null; |
|
|
|
if (!queue) { |
|
return inst.state; |
|
} |
|
|
|
if (replace && queue.length === 1) { |
|
return queue[0]; |
|
} |
|
|
|
var nextState = _assign({}, replace ? queue[0] : inst.state); |
|
for (var i = replace ? 1 : 0; i < queue.length; i++) { |
|
var partial = queue[i]; |
|
_assign(nextState, typeof partial === 'function' ? partial.call(inst, nextState, props, context) : partial); |
|
} |
|
|
|
return nextState; |
|
}, |
|
|
|
/** |
|
* Merges new props and state, notifies delegate methods of update and |
|
* performs update. |
|
* |
|
* @param {ReactElement} nextElement Next element |
|
* @param {object} nextProps Next public object to set as properties. |
|
* @param {?object} nextState Next object to set as state. |
|
* @param {?object} nextContext Next public object to set as context. |
|
* @param {ReactReconcileTransaction} transaction |
|
* @param {?object} unmaskedContext |
|
* @private |
|
*/ |
|
_performComponentUpdate: function (nextElement, nextProps, nextState, nextContext, transaction, unmaskedContext) { |
|
var _this2 = this; |
|
|
|
var inst = this._instance; |
|
|
|
var hasComponentDidUpdate = Boolean(inst.componentDidUpdate); |
|
var prevProps; |
|
var prevState; |
|
var prevContext; |
|
if (hasComponentDidUpdate) { |
|
prevProps = inst.props; |
|
prevState = inst.state; |
|
prevContext = inst.context; |
|
} |
|
|
|
if (inst.componentWillUpdate) { |
|
if ("development" !== 'production') { |
|
measureLifeCyclePerf(function () { |
|
return inst.componentWillUpdate(nextProps, nextState, nextContext); |
|
}, this._debugID, 'componentWillUpdate'); |
|
} else { |
|
inst.componentWillUpdate(nextProps, nextState, nextContext); |
|
} |
|
} |
|
|
|
this._currentElement = nextElement; |
|
this._context = unmaskedContext; |
|
inst.props = nextProps; |
|
inst.state = nextState; |
|
inst.context = nextContext; |
|
|
|
this._updateRenderedComponent(transaction, unmaskedContext); |
|
|
|
if (hasComponentDidUpdate) { |
|
if ("development" !== 'production') { |
|
transaction.getReactMountReady().enqueue(function () { |
|
measureLifeCyclePerf(inst.componentDidUpdate.bind(inst, prevProps, prevState, prevContext), _this2._debugID, 'componentDidUpdate'); |
|
}); |
|
} else { |
|
transaction.getReactMountReady().enqueue(inst.componentDidUpdate.bind(inst, prevProps, prevState, prevContext), inst); |
|
} |
|
} |
|
}, |
|
|
|
/** |
|
* Call the component's `render` method and update the DOM accordingly. |
|
* |
|
* @param {ReactReconcileTransaction} transaction |
|
* @internal |
|
*/ |
|
_updateRenderedComponent: function (transaction, context) { |
|
var prevComponentInstance = this._renderedComponent; |
|
var prevRenderedElement = prevComponentInstance._currentElement; |
|
var nextRenderedElement = this._renderValidatedComponent(); |
|
|
|
var debugID = 0; |
|
if ("development" !== 'production') { |
|
debugID = this._debugID; |
|
} |
|
|
|
if (shouldUpdateReactComponent(prevRenderedElement, nextRenderedElement)) { |
|
ReactReconciler.receiveComponent(prevComponentInstance, nextRenderedElement, transaction, this._processChildContext(context)); |
|
} else { |
|
var oldHostNode = ReactReconciler.getHostNode(prevComponentInstance); |
|
ReactReconciler.unmountComponent(prevComponentInstance, false); |
|
|
|
var nodeType = ReactNodeTypes.getType(nextRenderedElement); |
|
this._renderedNodeType = nodeType; |
|
var child = this._instantiateReactComponent(nextRenderedElement, nodeType !== ReactNodeTypes.EMPTY /* shouldHaveDebugID */ |
|
); |
|
this._renderedComponent = child; |
|
|
|
var nextMarkup = ReactReconciler.mountComponent(child, transaction, this._hostParent, this._hostContainerInfo, this._processChildContext(context), debugID); |
|
|
|
if ("development" !== 'production') { |
|
if (debugID !== 0) { |
|
var childDebugIDs = child._debugID !== 0 ? [child._debugID] : []; |
|
ReactInstrumentation.debugTool.onSetChildren(debugID, childDebugIDs); |
|
} |
|
} |
|
|
|
this._replaceNodeWithMarkup(oldHostNode, nextMarkup, prevComponentInstance); |
|
} |
|
}, |
|
|
|
/** |
|
* Overridden in shallow rendering. |
|
* |
|
* @protected |
|
*/ |
|
_replaceNodeWithMarkup: function (oldHostNode, nextMarkup, prevInstance) { |
|
ReactComponentEnvironment.replaceNodeWithMarkup(oldHostNode, nextMarkup, prevInstance); |
|
}, |
|
|
|
/** |
|
* @protected |
|
*/ |
|
_renderValidatedComponentWithoutOwnerOrContext: function () { |
|
var inst = this._instance; |
|
var renderedElement; |
|
|
|
if ("development" !== 'production') { |
|
renderedElement = measureLifeCyclePerf(function () { |
|
return inst.render(); |
|
}, this._debugID, 'render'); |
|
} else { |
|
renderedElement = inst.render(); |
|
} |
|
|
|
if ("development" !== 'production') { |
|
// We allow auto-mocks to proceed as if they're returning null. |
|
if (renderedElement === undefined && inst.render._isMockFunction) { |
|
// This is probably bad practice. Consider warning here and |
|
// deprecating this convenience. |
|
renderedElement = null; |
|
} |
|
} |
|
|
|
return renderedElement; |
|
}, |
|
|
|
/** |
|
* @private |
|
*/ |
|
_renderValidatedComponent: function () { |
|
var renderedElement; |
|
if ("development" !== 'production' || this._compositeType !== CompositeTypes.StatelessFunctional) { |
|
ReactCurrentOwner.current = this; |
|
try { |
|
renderedElement = this._renderValidatedComponentWithoutOwnerOrContext(); |
|
} finally { |
|
ReactCurrentOwner.current = null; |
|
} |
|
} else { |
|
renderedElement = this._renderValidatedComponentWithoutOwnerOrContext(); |
|
} |
|
!( |
|
// TODO: An `isValidNode` function would probably be more appropriate |
|
renderedElement === null || renderedElement === false || React.isValidElement(renderedElement)) ? "development" !== 'production' ? invariant(false, '%s.render(): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.', this.getName() || 'ReactCompositeComponent') : _prodInvariant('109', this.getName() || 'ReactCompositeComponent') : void 0; |
|
|
|
return renderedElement; |
|
}, |
|
|
|
/** |
|
* 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) { |
|
var inst = this.getPublicInstance(); |
|
!(inst != null) ? "development" !== 'production' ? invariant(false, 'Stateless function components cannot have refs.') : _prodInvariant('110') : void 0; |
|
var publicComponentInstance = component.getPublicInstance(); |
|
if ("development" !== 'production') { |
|
var componentName = component && component.getName ? component.getName() : 'a component'; |
|
"development" !== 'production' ? warning(publicComponentInstance != null || component._compositeType !== CompositeTypes.StatelessFunctional, 'Stateless function components cannot be given refs ' + '(See ref "%s" in %s created by %s). ' + 'Attempts to access this ref will fail.', ref, componentName, this.getName()) : void 0; |
|
} |
|
var refs = inst.refs === emptyObject ? inst.refs = {} : inst.refs; |
|
refs[ref] = publicComponentInstance; |
|
}, |
|
|
|
/** |
|
* Detaches a reference name. |
|
* |
|
* @param {string} ref Name to dereference. |
|
* @final |
|
* @private |
|
*/ |
|
detachRef: function (ref) { |
|
var refs = this.getPublicInstance().refs; |
|
delete refs[ref]; |
|
}, |
|
|
|
/** |
|
* Get a text description of the component that can be used to identify it |
|
* in error messages. |
|
* @return {string} The name or null. |
|
* @internal |
|
*/ |
|
getName: function () { |
|
var type = this._currentElement.type; |
|
var constructor = this._instance && this._instance.constructor; |
|
return type.displayName || constructor && constructor.displayName || type.name || constructor && constructor.name || null; |
|
}, |
|
|
|
/** |
|
* Get the publicly accessible representation of this component - i.e. what |
|
* is exposed by refs and returned by render. Can be null for stateless |
|
* components. |
|
* |
|
* @return {ReactComponent} the public component instance. |
|
* @internal |
|
*/ |
|
getPublicInstance: function () { |
|
var inst = this._instance; |
|
if (this._compositeType === CompositeTypes.StatelessFunctional) { |
|
return null; |
|
} |
|
return inst; |
|
}, |
|
|
|
// Stub |
|
_instantiateReactComponent: null |
|
|
|
}; |
|
|
|
module.exports = ReactCompositeComponent; |
|
},{"104":104,"125":125,"129":129,"133":133,"134":134,"143":143,"150":150,"156":156,"157":157,"158":158,"29":29,"55":55,"63":63,"64":64,"69":69,"75":75}],31:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
/* globals __REACT_DEVTOOLS_GLOBAL_HOOK__*/ |
|
|
|
'use strict'; |
|
|
|
var ReactDOMComponentTree = _dereq_(34); |
|
var ReactDefaultInjection = _dereq_(52); |
|
var ReactMount = _dereq_(67); |
|
var ReactReconciler = _dereq_(75); |
|
var ReactUpdates = _dereq_(82); |
|
var ReactVersion = _dereq_(83); |
|
|
|
var findDOMNode = _dereq_(108); |
|
var getHostComponentFromComposite = _dereq_(115); |
|
var renderSubtreeIntoContainer = _dereq_(126); |
|
var warning = _dereq_(157); |
|
|
|
ReactDefaultInjection.inject(); |
|
|
|
var ReactDOM = { |
|
findDOMNode: findDOMNode, |
|
render: ReactMount.render, |
|
unmountComponentAtNode: ReactMount.unmountComponentAtNode, |
|
version: ReactVersion, |
|
|
|
/* eslint-disable camelcase */ |
|
unstable_batchedUpdates: ReactUpdates.batchedUpdates, |
|
unstable_renderSubtreeIntoContainer: renderSubtreeIntoContainer |
|
}; |
|
|
|
// Inject the runtime into a devtools global hook regardless of browser. |
|
// Allows for debugging when the hook is injected on the page. |
|
if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject === 'function') { |
|
__REACT_DEVTOOLS_GLOBAL_HOOK__.inject({ |
|
ComponentTree: { |
|
getClosestInstanceFromNode: ReactDOMComponentTree.getClosestInstanceFromNode, |
|
getNodeFromInstance: function (inst) { |
|
// inst is an internal instance (but could be a composite) |
|
if (inst._renderedComponent) { |
|
inst = getHostComponentFromComposite(inst); |
|
} |
|
if (inst) { |
|
return ReactDOMComponentTree.getNodeFromInstance(inst); |
|
} else { |
|
return null; |
|
} |
|
} |
|
}, |
|
Mount: ReactMount, |
|
Reconciler: ReactReconciler |
|
}); |
|
} |
|
|
|
if ("development" !== 'production') { |
|
var ExecutionEnvironment = _dereq_(136); |
|
if (ExecutionEnvironment.canUseDOM && window.top === window.self) { |
|
|
|
// First check if devtools is not installed |
|
if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') { |
|
// If we're in Chrome or Firefox, provide a download link if not installed. |
|
if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) { |
|
// Firefox does not have the issue with devtools loaded over file:// |
|
var showFileUrlMessage = window.location.protocol.indexOf('http') === -1 && navigator.userAgent.indexOf('Firefox') === -1; |
|
console.debug('Download the React DevTools ' + (showFileUrlMessage ? 'and use an HTTP server (instead of a file: URL) ' : '') + 'for a better development experience: ' + 'https://fb.me/react-devtools'); |
|
} |
|
} |
|
|
|
var testFunc = function testFn() {}; |
|
"development" !== 'production' ? warning((testFunc.name || testFunc.toString()).indexOf('testFn') !== -1, 'It looks like you\'re using a minified copy of the development build ' + 'of React. When deploying React apps to production, make sure to use ' + 'the production build which skips development warnings and is faster. ' + 'See https://fb.me/react-minification for more details.') : void 0; |
|
|
|
// If we're in IE8, check to see if we are in compatibility mode and provide |
|
// information on preventing compatibility mode |
|
var ieCompatibilityMode = document.documentMode && document.documentMode < 8; |
|
|
|
"development" !== 'production' ? warning(!ieCompatibilityMode, 'Internet Explorer is running in compatibility mode; please add the ' + 'following tag to your HTML to prevent this from happening: ' + '<meta http-equiv="X-UA-Compatible" content="IE=edge" />') : void 0; |
|
|
|
var expectedFeatures = [ |
|
// shims |
|
Array.isArray, Array.prototype.every, Array.prototype.forEach, Array.prototype.indexOf, Array.prototype.map, Date.now, Function.prototype.bind, Object.keys, String.prototype.trim]; |
|
|
|
for (var i = 0; i < expectedFeatures.length; i++) { |
|
if (!expectedFeatures[i]) { |
|
"development" !== 'production' ? warning(false, 'One or more ES5 shims expected by React are not available: ' + 'https://fb.me/react-warning-polyfills') : void 0; |
|
break; |
|
} |
|
} |
|
} |
|
} |
|
|
|
if ("development" !== 'production') { |
|
var ReactInstrumentation = _dereq_(64); |
|
var ReactDOMUnknownPropertyHook = _dereq_(49); |
|
var ReactDOMNullInputValuePropHook = _dereq_(41); |
|
var ReactDOMInvalidARIAHook = _dereq_(40); |
|
|
|
ReactInstrumentation.debugTool.addHook(ReactDOMUnknownPropertyHook); |
|
ReactInstrumentation.debugTool.addHook(ReactDOMNullInputValuePropHook); |
|
ReactInstrumentation.debugTool.addHook(ReactDOMInvalidARIAHook); |
|
} |
|
|
|
module.exports = ReactDOM; |
|
},{"108":108,"115":115,"126":126,"136":136,"157":157,"34":34,"40":40,"41":41,"49":49,"52":52,"64":64,"67":67,"75":75,"82":82,"83":83}],32:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
/* global hasOwnProperty:true */ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125), |
|
_assign = _dereq_(158); |
|
|
|
var AutoFocusUtils = _dereq_(2); |
|
var CSSPropertyOperations = _dereq_(5); |
|
var DOMLazyTree = _dereq_(9); |
|
var DOMNamespaces = _dereq_(10); |
|
var DOMProperty = _dereq_(11); |
|
var DOMPropertyOperations = _dereq_(12); |
|
var EventPluginHub = _dereq_(17); |
|
var EventPluginRegistry = _dereq_(18); |
|
var ReactBrowserEventEmitter = _dereq_(26); |
|
var ReactDOMComponentFlags = _dereq_(33); |
|
var ReactDOMComponentTree = _dereq_(34); |
|
var ReactDOMInput = _dereq_(39); |
|
var ReactDOMOption = _dereq_(42); |
|
var ReactDOMSelect = _dereq_(43); |
|
var ReactDOMTextarea = _dereq_(46); |
|
var ReactInstrumentation = _dereq_(64); |
|
var ReactMultiChild = _dereq_(68); |
|
var ReactServerRenderingTransaction = _dereq_(77); |
|
|
|
var emptyFunction = _dereq_(142); |
|
var escapeTextContentForBrowser = _dereq_(107); |
|
var invariant = _dereq_(150); |
|
var isEventSupported = _dereq_(122); |
|
var shallowEqual = _dereq_(156); |
|
var validateDOMNesting = _dereq_(131); |
|
var warning = _dereq_(157); |
|
|
|
var Flags = ReactDOMComponentFlags; |
|
var deleteListener = EventPluginHub.deleteListener; |
|
var getNode = ReactDOMComponentTree.getNodeFromInstance; |
|
var listenTo = ReactBrowserEventEmitter.listenTo; |
|
var registrationNameModules = EventPluginRegistry.registrationNameModules; |
|
|
|
// For quickly matching children type, to test if can be treated as content. |
|
var CONTENT_TYPES = { 'string': true, 'number': true }; |
|
|
|
var STYLE = 'style'; |
|
var HTML = '__html'; |
|
var RESERVED_PROPS = { |
|
children: null, |
|
dangerouslySetInnerHTML: null, |
|
suppressContentEditableWarning: null |
|
}; |
|
|
|
// Node type for document fragments (Node.DOCUMENT_FRAGMENT_NODE). |
|
var DOC_FRAGMENT_TYPE = 11; |
|
|
|
function getDeclarationErrorAddendum(internalInstance) { |
|
if (internalInstance) { |
|
var owner = internalInstance._currentElement._owner || null; |
|
if (owner) { |
|
var name = owner.getName(); |
|
if (name) { |
|
return ' This DOM node was rendered by `' + name + '`.'; |
|
} |
|
} |
|
} |
|
return ''; |
|
} |
|
|
|
function friendlyStringify(obj) { |
|
if (typeof obj === 'object') { |
|
if (Array.isArray(obj)) { |
|
return '[' + obj.map(friendlyStringify).join(', ') + ']'; |
|
} else { |
|
var pairs = []; |
|
for (var key in obj) { |
|
if (Object.prototype.hasOwnProperty.call(obj, key)) { |
|
var keyEscaped = /^[a-z$_][\w$_]*$/i.test(key) ? key : JSON.stringify(key); |
|
pairs.push(keyEscaped + ': ' + friendlyStringify(obj[key])); |
|
} |
|
} |
|
return '{' + pairs.join(', ') + '}'; |
|
} |
|
} else if (typeof obj === 'string') { |
|
return JSON.stringify(obj); |
|
} else if (typeof obj === 'function') { |
|
return '[function object]'; |
|
} |
|
// Differs from JSON.stringify in that undefined because undefined and that |
|
// inf and nan don't become null |
|
return String(obj); |
|
} |
|
|
|
var styleMutationWarning = {}; |
|
|
|
function checkAndWarnForMutatedStyle(style1, style2, component) { |
|
if (style1 == null || style2 == null) { |
|
return; |
|
} |
|
if (shallowEqual(style1, style2)) { |
|
return; |
|
} |
|
|
|
var componentName = component._tag; |
|
var owner = component._currentElement._owner; |
|
var ownerName; |
|
if (owner) { |
|
ownerName = owner.getName(); |
|
} |
|
|
|
var hash = ownerName + '|' + componentName; |
|
|
|
if (styleMutationWarning.hasOwnProperty(hash)) { |
|
return; |
|
} |
|
|
|
styleMutationWarning[hash] = true; |
|
|
|
"development" !== 'production' ? warning(false, '`%s` was passed a style object that has previously been mutated. ' + 'Mutating `style` is deprecated. Consider cloning it beforehand. Check ' + 'the `render` %s. Previous style: %s. Mutated style: %s.', componentName, owner ? 'of `' + ownerName + '`' : 'using <' + componentName + '>', friendlyStringify(style1), friendlyStringify(style2)) : void 0; |
|
} |
|
|
|
/** |
|
* @param {object} component |
|
* @param {?object} props |
|
*/ |
|
function assertValidProps(component, props) { |
|
if (!props) { |
|
return; |
|
} |
|
// Note the use of `==` which checks for null or undefined. |
|
if (voidElementTags[component._tag]) { |
|
!(props.children == null && props.dangerouslySetInnerHTML == null) ? "development" !== 'production' ? invariant(false, '%s is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`.%s', component._tag, component._currentElement._owner ? ' Check the render method of ' + component._currentElement._owner.getName() + '.' : '') : _prodInvariant('137', component._tag, component._currentElement._owner ? ' Check the render method of ' + component._currentElement._owner.getName() + '.' : '') : void 0; |
|
} |
|
if (props.dangerouslySetInnerHTML != null) { |
|
!(props.children == null) ? "development" !== 'production' ? invariant(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : _prodInvariant('60') : void 0; |
|
!(typeof props.dangerouslySetInnerHTML === 'object' && HTML in props.dangerouslySetInnerHTML) ? "development" !== 'production' ? invariant(false, '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. Please visit https://fb.me/react-invariant-dangerously-set-inner-html for more information.') : _prodInvariant('61') : void 0; |
|
} |
|
if ("development" !== 'production') { |
|
"development" !== 'production' ? warning(props.innerHTML == null, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.') : void 0; |
|
"development" !== 'production' ? warning(props.suppressContentEditableWarning || !props.contentEditable || props.children == null, 'A component is `contentEditable` and contains `children` managed by ' + 'React. It is now your responsibility to guarantee that none of ' + 'those nodes are unexpectedly modified or duplicated. This is ' + 'probably not intentional.') : void 0; |
|
"development" !== 'production' ? warning(props.onFocusIn == null && props.onFocusOut == null, 'React uses onFocus and onBlur instead of onFocusIn and onFocusOut. ' + 'All React events are normalized to bubble, so onFocusIn and onFocusOut ' + 'are not needed/supported by React.') : void 0; |
|
} |
|
!(props.style == null || typeof props.style === 'object') ? "development" !== 'production' ? invariant(false, 'The `style` prop expects a mapping from style properties to values, not a string. For example, style={{marginRight: spacing + \'em\'}} when using JSX.%s', getDeclarationErrorAddendum(component)) : _prodInvariant('62', getDeclarationErrorAddendum(component)) : void 0; |
|
} |
|
|
|
function enqueuePutListener(inst, registrationName, listener, transaction) { |
|
if (transaction instanceof ReactServerRenderingTransaction) { |
|
return; |
|
} |
|
if ("development" !== 'production') { |
|
// IE8 has no API for event capturing and the `onScroll` event doesn't |
|
// bubble. |
|
"development" !== 'production' ? warning(registrationName !== 'onScroll' || isEventSupported('scroll', true), 'This browser doesn\'t support the `onScroll` event') : void 0; |
|
} |
|
var containerInfo = inst._hostContainerInfo; |
|
var isDocumentFragment = containerInfo._node && containerInfo._node.nodeType === DOC_FRAGMENT_TYPE; |
|
var doc = isDocumentFragment ? containerInfo._node : containerInfo._ownerDocument; |
|
listenTo(registrationName, doc); |
|
transaction.getReactMountReady().enqueue(putListener, { |
|
inst: inst, |
|
registrationName: registrationName, |
|
listener: listener |
|
}); |
|
} |
|
|
|
function putListener() { |
|
var listenerToPut = this; |
|
EventPluginHub.putListener(listenerToPut.inst, listenerToPut.registrationName, listenerToPut.listener); |
|
} |
|
|
|
function inputPostMount() { |
|
var inst = this; |
|
ReactDOMInput.postMountWrapper(inst); |
|
} |
|
|
|
function textareaPostMount() { |
|
var inst = this; |
|
ReactDOMTextarea.postMountWrapper(inst); |
|
} |
|
|
|
function optionPostMount() { |
|
var inst = this; |
|
ReactDOMOption.postMountWrapper(inst); |
|
} |
|
|
|
var setAndValidateContentChildDev = emptyFunction; |
|
if ("development" !== 'production') { |
|
setAndValidateContentChildDev = function (content) { |
|
var hasExistingContent = this._contentDebugID != null; |
|
var debugID = this._debugID; |
|
// This ID represents the inlined child that has no backing instance: |
|
var contentDebugID = -debugID; |
|
|
|
if (content == null) { |
|
if (hasExistingContent) { |
|
ReactInstrumentation.debugTool.onUnmountComponent(this._contentDebugID); |
|
} |
|
this._contentDebugID = null; |
|
return; |
|
} |
|
|
|
validateDOMNesting(null, String(content), this, this._ancestorInfo); |
|
this._contentDebugID = contentDebugID; |
|
if (hasExistingContent) { |
|
ReactInstrumentation.debugTool.onBeforeUpdateComponent(contentDebugID, content); |
|
ReactInstrumentation.debugTool.onUpdateComponent(contentDebugID); |
|
} else { |
|
ReactInstrumentation.debugTool.onBeforeMountComponent(contentDebugID, content, debugID); |
|
ReactInstrumentation.debugTool.onMountComponent(contentDebugID); |
|
ReactInstrumentation.debugTool.onSetChildren(debugID, [contentDebugID]); |
|
} |
|
}; |
|
} |
|
|
|
// There are so many media events, it makes sense to just |
|
// maintain a list rather than create a `trapBubbledEvent` for each |
|
var mediaEvents = { |
|
topAbort: 'abort', |
|
topCanPlay: 'canplay', |
|
topCanPlayThrough: 'canplaythrough', |
|
topDurationChange: 'durationchange', |
|
topEmptied: 'emptied', |
|
topEncrypted: 'encrypted', |
|
topEnded: 'ended', |
|
topError: 'error', |
|
topLoadedData: 'loadeddata', |
|
topLoadedMetadata: 'loadedmetadata', |
|
topLoadStart: 'loadstart', |
|
topPause: 'pause', |
|
topPlay: 'play', |
|
topPlaying: 'playing', |
|
topProgress: 'progress', |
|
topRateChange: 'ratechange', |
|
topSeeked: 'seeked', |
|
topSeeking: 'seeking', |
|
topStalled: 'stalled', |
|
topSuspend: 'suspend', |
|
topTimeUpdate: 'timeupdate', |
|
topVolumeChange: 'volumechange', |
|
topWaiting: 'waiting' |
|
}; |
|
|
|
function trapBubbledEventsLocal() { |
|
var inst = this; |
|
// If a component renders to null or if another component fatals and causes |
|
// the state of the tree to be corrupted, `node` here can be null. |
|
!inst._rootNodeID ? "development" !== 'production' ? invariant(false, 'Must be mounted to trap events') : _prodInvariant('63') : void 0; |
|
var node = getNode(inst); |
|
!node ? "development" !== 'production' ? invariant(false, 'trapBubbledEvent(...): Requires node to be rendered.') : _prodInvariant('64') : void 0; |
|
|
|
switch (inst._tag) { |
|
case 'iframe': |
|
case 'object': |
|
inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent('topLoad', 'load', node)]; |
|
break; |
|
case 'video': |
|
case 'audio': |
|
|
|
inst._wrapperState.listeners = []; |
|
// Create listener for each media event |
|
for (var event in mediaEvents) { |
|
if (mediaEvents.hasOwnProperty(event)) { |
|
inst._wrapperState.listeners.push(ReactBrowserEventEmitter.trapBubbledEvent(event, mediaEvents[event], node)); |
|
} |
|
} |
|
break; |
|
case 'source': |
|
inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent('topError', 'error', node)]; |
|
break; |
|
case 'img': |
|
inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent('topError', 'error', node), ReactBrowserEventEmitter.trapBubbledEvent('topLoad', 'load', node)]; |
|
break; |
|
case 'form': |
|
inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent('topReset', 'reset', node), ReactBrowserEventEmitter.trapBubbledEvent('topSubmit', 'submit', node)]; |
|
break; |
|
case 'input': |
|
case 'select': |
|
case 'textarea': |
|
inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent('topInvalid', 'invalid', node)]; |
|
break; |
|
} |
|
} |
|
|
|
function postUpdateSelectWrapper() { |
|
ReactDOMSelect.postUpdateWrapper(this); |
|
} |
|
|
|
// For HTML, certain tags should omit their close tag. We keep a whitelist for |
|
// those special-case tags. |
|
|
|
var omittedCloseTags = { |
|
'area': true, |
|
'base': true, |
|
'br': true, |
|
'col': true, |
|
'embed': true, |
|
'hr': true, |
|
'img': true, |
|
'input': true, |
|
'keygen': true, |
|
'link': true, |
|
'meta': true, |
|
'param': true, |
|
'source': true, |
|
'track': true, |
|
'wbr': true |
|
}; |
|
|
|
var newlineEatingTags = { |
|
'listing': true, |
|
'pre': true, |
|
'textarea': true |
|
}; |
|
|
|
// For HTML, certain tags cannot have children. This has the same purpose as |
|
// `omittedCloseTags` except that `menuitem` should still have its closing tag. |
|
|
|
var voidElementTags = _assign({ |
|
'menuitem': true |
|
}, omittedCloseTags); |
|
|
|
// We accept any tag to be rendered but since this gets injected into arbitrary |
|
// HTML, we want to make sure that it's a safe tag. |
|
// http://www.w3.org/TR/REC-xml/#NT-Name |
|
|
|
var VALID_TAG_REGEX = /^[a-zA-Z][a-zA-Z:_\.\-\d]*$/; // Simplified subset |
|
var validatedTagCache = {}; |
|
var hasOwnProperty = {}.hasOwnProperty; |
|
|
|
function validateDangerousTag(tag) { |
|
if (!hasOwnProperty.call(validatedTagCache, tag)) { |
|
!VALID_TAG_REGEX.test(tag) ? "development" !== 'production' ? invariant(false, 'Invalid tag: %s', tag) : _prodInvariant('65', tag) : void 0; |
|
validatedTagCache[tag] = true; |
|
} |
|
} |
|
|
|
function isCustomComponent(tagName, props) { |
|
return tagName.indexOf('-') >= 0 || props.is != null; |
|
} |
|
|
|
var globalIdCounter = 1; |
|
|
|
/** |
|
* Creates a new React class that is idempotent and capable of containing other |
|
* React components. It accepts event listeners and DOM properties that are |
|
* 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. |
|
* |
|
* @constructor ReactDOMComponent |
|
* @extends ReactMultiChild |
|
*/ |
|
function ReactDOMComponent(element) { |
|
var tag = element.type; |
|
validateDangerousTag(tag); |
|
this._currentElement = element; |
|
this._tag = tag.toLowerCase(); |
|
this._namespaceURI = null; |
|
this._renderedChildren = null; |
|
this._previousStyle = null; |
|
this._previousStyleCopy = null; |
|
this._hostNode = null; |
|
this._hostParent = null; |
|
this._rootNodeID = 0; |
|
this._domID = 0; |
|
this._hostContainerInfo = null; |
|
this._wrapperState = null; |
|
this._topLevelWrapper = null; |
|
this._flags = 0; |
|
if ("development" !== 'production') { |
|
this._ancestorInfo = null; |
|
setAndValidateContentChildDev.call(this, null); |
|
} |
|
} |
|
|
|
ReactDOMComponent.displayName = 'ReactDOMComponent'; |
|
|
|
ReactDOMComponent.Mixin = { |
|
|
|
/** |
|
* Generates root tag markup then recurses. This method has side effects and |
|
* is not idempotent. |
|
* |
|
* @internal |
|
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction |
|
* @param {?ReactDOMComponent} the parent component instance |
|
* @param {?object} info about the host container |
|
* @param {object} context |
|
* @return {string} The computed markup. |
|
*/ |
|
mountComponent: function (transaction, hostParent, hostContainerInfo, context) { |
|
this._rootNodeID = globalIdCounter++; |
|
this._domID = hostContainerInfo._idCounter++; |
|
this._hostParent = hostParent; |
|
this._hostContainerInfo = hostContainerInfo; |
|
|
|
var props = this._currentElement.props; |
|
|
|
switch (this._tag) { |
|
case 'audio': |
|
case 'form': |
|
case 'iframe': |
|
case 'img': |
|
case 'link': |
|
case 'object': |
|
case 'source': |
|
case 'video': |
|
this._wrapperState = { |
|
listeners: null |
|
}; |
|
transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this); |
|
break; |
|
case 'input': |
|
ReactDOMInput.mountWrapper(this, props, hostParent); |
|
props = ReactDOMInput.getHostProps(this, props); |
|
transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this); |
|
break; |
|
case 'option': |
|
ReactDOMOption.mountWrapper(this, props, hostParent); |
|
props = ReactDOMOption.getHostProps(this, props); |
|
break; |
|
case 'select': |
|
ReactDOMSelect.mountWrapper(this, props, hostParent); |
|
props = ReactDOMSelect.getHostProps(this, props); |
|
transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this); |
|
break; |
|
case 'textarea': |
|
ReactDOMTextarea.mountWrapper(this, props, hostParent); |
|
props = ReactDOMTextarea.getHostProps(this, props); |
|
transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this); |
|
break; |
|
} |
|
|
|
assertValidProps(this, props); |
|
|
|
// We create tags in the namespace of their parent container, except HTML |
|
// tags get no namespace. |
|
var namespaceURI; |
|
var parentTag; |
|
if (hostParent != null) { |
|
namespaceURI = hostParent._namespaceURI; |
|
parentTag = hostParent._tag; |
|
} else if (hostContainerInfo._tag) { |
|
namespaceURI = hostContainerInfo._namespaceURI; |
|
parentTag = hostContainerInfo._tag; |
|
} |
|
if (namespaceURI == null || namespaceURI === DOMNamespaces.svg && parentTag === 'foreignobject') { |
|
namespaceURI = DOMNamespaces.html; |
|
} |
|
if (namespaceURI === DOMNamespaces.html) { |
|
if (this._tag === 'svg') { |
|
namespaceURI = DOMNamespaces.svg; |
|
} else if (this._tag === 'math') { |
|
namespaceURI = DOMNamespaces.mathml; |
|
} |
|
} |
|
this._namespaceURI = namespaceURI; |
|
|
|
if ("development" !== 'production') { |
|
var parentInfo; |
|
if (hostParent != null) { |
|
parentInfo = hostParent._ancestorInfo; |
|
} else if (hostContainerInfo._tag) { |
|
parentInfo = hostContainerInfo._ancestorInfo; |
|
} |
|
if (parentInfo) { |
|
// parentInfo should always be present except for the top-level |
|
// component when server rendering |
|
validateDOMNesting(this._tag, null, this, parentInfo); |
|
} |
|
this._ancestorInfo = validateDOMNesting.updatedAncestorInfo(parentInfo, this._tag, this); |
|
} |
|
|
|
var mountImage; |
|
if (transaction.useCreateElement) { |
|
var ownerDocument = hostContainerInfo._ownerDocument; |
|
var el; |
|
if (namespaceURI === DOMNamespaces.html) { |
|
if (this._tag === 'script') { |
|
// Create the script via .innerHTML so its "parser-inserted" flag is |
|
// set to true and it does not execute |
|
var div = ownerDocument.createElement('div'); |
|
var type = this._currentElement.type; |
|
div.innerHTML = '<' + type + '></' + type + '>'; |
|
el = div.removeChild(div.firstChild); |
|
} else if (props.is) { |
|
el = ownerDocument.createElement(this._currentElement.type, props.is); |
|
} else { |
|
// Separate else branch instead of using `props.is || undefined` above becuase of a Firefox bug. |
|
// See discussion in https://github.com/facebook/react/pull/6896 |
|
// and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240 |
|
el = ownerDocument.createElement(this._currentElement.type); |
|
} |
|
} else { |
|
el = ownerDocument.createElementNS(namespaceURI, this._currentElement.type); |
|
} |
|
ReactDOMComponentTree.precacheNode(this, el); |
|
this._flags |= Flags.hasCachedChildNodes; |
|
if (!this._hostParent) { |
|
DOMPropertyOperations.setAttributeForRoot(el); |
|
} |
|
this._updateDOMProperties(null, props, transaction); |
|
var lazyTree = DOMLazyTree(el); |
|
this._createInitialChildren(transaction, props, context, lazyTree); |
|
mountImage = lazyTree; |
|
} else { |
|
var tagOpen = this._createOpenTagMarkupAndPutListeners(transaction, props); |
|
var tagContent = this._createContentMarkup(transaction, props, context); |
|
if (!tagContent && omittedCloseTags[this._tag]) { |
|
mountImage = tagOpen + '/>'; |
|
} else { |
|
mountImage = tagOpen + '>' + tagContent + '</' + this._currentElement.type + '>'; |
|
} |
|
} |
|
|
|
switch (this._tag) { |
|
case 'input': |
|
transaction.getReactMountReady().enqueue(inputPostMount, this); |
|
if (props.autoFocus) { |
|
transaction.getReactMountReady().enqueue(AutoFocusUtils.focusDOMComponent, this); |
|
} |
|
break; |
|
case 'textarea': |
|
transaction.getReactMountReady().enqueue(textareaPostMount, this); |
|
if (props.autoFocus) { |
|
transaction.getReactMountReady().enqueue(AutoFocusUtils.focusDOMComponent, this); |
|
} |
|
break; |
|
case 'select': |
|
if (props.autoFocus) { |
|
transaction.getReactMountReady().enqueue(AutoFocusUtils.focusDOMComponent, this); |
|
} |
|
break; |
|
case 'button': |
|
if (props.autoFocus) { |
|
transaction.getReactMountReady().enqueue(AutoFocusUtils.focusDOMComponent, this); |
|
} |
|
break; |
|
case 'option': |
|
transaction.getReactMountReady().enqueue(optionPostMount, this); |
|
break; |
|
} |
|
|
|
return mountImage; |
|
}, |
|
|
|
/** |
|
* 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 |
|
* @param {object} props |
|
* @return {string} Markup of opening tag. |
|
*/ |
|
_createOpenTagMarkupAndPutListeners: function (transaction, props) { |
|
var ret = '<' + this._currentElement.type; |
|
|
|
for (var propKey in props) { |
|
if (!props.hasOwnProperty(propKey)) { |
|
continue; |
|
} |
|
var propValue = props[propKey]; |
|
if (propValue == null) { |
|
continue; |
|
} |
|
if (registrationNameModules.hasOwnProperty(propKey)) { |
|
if (propValue) { |
|
enqueuePutListener(this, propKey, propValue, transaction); |
|
} |
|
} else { |
|
if (propKey === STYLE) { |
|
if (propValue) { |
|
if ("development" !== 'production') { |
|
// See `_updateDOMProperties`. style block |
|
this._previousStyle = propValue; |
|
} |
|
propValue = this._previousStyleCopy = _assign({}, props.style); |
|
} |
|
propValue = CSSPropertyOperations.createMarkupForStyles(propValue, this); |
|
} |
|
var markup = null; |
|
if (this._tag != null && isCustomComponent(this._tag, props)) { |
|
if (!RESERVED_PROPS.hasOwnProperty(propKey)) { |
|
markup = DOMPropertyOperations.createMarkupForCustomAttribute(propKey, propValue); |
|
} |
|
} else { |
|
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; |
|
} |
|
|
|
if (!this._hostParent) { |
|
ret += ' ' + DOMPropertyOperations.createMarkupForRoot(); |
|
} |
|
ret += ' ' + DOMPropertyOperations.createMarkupForID(this._domID); |
|
return ret; |
|
}, |
|
|
|
/** |
|
* Creates markup for the content between the tags. |
|
* |
|
* @private |
|
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction |
|
* @param {object} props |
|
* @param {object} context |
|
* @return {string} Content markup. |
|
*/ |
|
_createContentMarkup: function (transaction, props, context) { |
|
var ret = ''; |
|
|
|
// Intentional use of != to avoid catching zero/false. |
|
var innerHTML = props.dangerouslySetInnerHTML; |
|
if (innerHTML != null) { |
|
if (innerHTML.__html != null) { |
|
ret = innerHTML.__html; |
|
} |
|
} else { |
|
var contentToUse = CONTENT_TYPES[typeof props.children] ? props.children : null; |
|
var childrenToUse = contentToUse != null ? null : props.children; |
|
if (contentToUse != null) { |
|
// TODO: Validate that text is allowed as a child of this node |
|
ret = escapeTextContentForBrowser(contentToUse); |
|
if ("development" !== 'production') { |
|
setAndValidateContentChildDev.call(this, contentToUse); |
|
} |
|
} else if (childrenToUse != null) { |
|
var mountImages = this.mountChildren(childrenToUse, transaction, context); |
|
ret = mountImages.join(''); |
|
} |
|
} |
|
if (newlineEatingTags[this._tag] && ret.charAt(0) === '\n') { |
|
// text/html ignores the first character in these tags if it's a newline |
|
// Prefer to break application/xml over text/html (for now) by adding |
|
// a newline specifically to get eaten by the parser. (Alternately for |
|
// textareas, replacing "^\n" with "\r\n" doesn't get eaten, and the first |
|
// \r is normalized out by HTMLTextAreaElement#value.) |
|
// See: <http://www.w3.org/TR/html-polyglot/#newlines-in-textarea-and-pre> |
|
// See: <http://www.w3.org/TR/html5/syntax.html#element-restrictions> |
|
// See: <http://www.w3.org/TR/html5/syntax.html#newlines> |
|
// See: Parsing of "textarea" "listing" and "pre" elements |
|
// from <http://www.w3.org/TR/html5/syntax.html#parsing-main-inbody> |
|
return '\n' + ret; |
|
} else { |
|
return ret; |
|
} |
|
}, |
|
|
|
_createInitialChildren: function (transaction, props, context, lazyTree) { |
|
// Intentional use of != to avoid catching zero/false. |
|
var innerHTML = props.dangerouslySetInnerHTML; |
|
if (innerHTML != null) { |
|
if (innerHTML.__html != null) { |
|
DOMLazyTree.queueHTML(lazyTree, innerHTML.__html); |
|
} |
|
} else { |
|
var contentToUse = CONTENT_TYPES[typeof props.children] ? props.children : null; |
|
var childrenToUse = contentToUse != null ? null : props.children; |
|
// TODO: Validate that text is allowed as a child of this node |
|
if (contentToUse != null) { |
|
// Avoid setting textContent when the text is empty. In IE11 setting |
|
// textContent on a text area will cause the placeholder to not |
|
// show within the textarea until it has been focused and blurred again. |
|
// https://github.com/facebook/react/issues/6731#issuecomment-254874553 |
|
if (contentToUse !== '') { |
|
if ("development" !== 'production') { |
|
setAndValidateContentChildDev.call(this, contentToUse); |
|
} |
|
DOMLazyTree.queueText(lazyTree, contentToUse); |
|
} |
|
} else if (childrenToUse != null) { |
|
var mountImages = this.mountChildren(childrenToUse, transaction, context); |
|
for (var i = 0; i < mountImages.length; i++) { |
|
DOMLazyTree.queueChild(lazyTree, mountImages[i]); |
|
} |
|
} |
|
} |
|
}, |
|
|
|
/** |
|
* Receives a next element and updates the component. |
|
* |
|
* @internal |
|
* @param {ReactElement} nextElement |
|
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction |
|
* @param {object} context |
|
*/ |
|
receiveComponent: function (nextElement, transaction, context) { |
|
var prevElement = this._currentElement; |
|
this._currentElement = nextElement; |
|
this.updateComponent(transaction, prevElement, nextElement, context); |
|
}, |
|
|
|
/** |
|
* Updates a DOM component after it has already been allocated and |
|
* attached to the DOM. Reconciles the root DOM node, then recurses. |
|
* |
|
* @param {ReactReconcileTransaction} transaction |
|
* @param {ReactElement} prevElement |
|
* @param {ReactElement} nextElement |
|
* @internal |
|
* @overridable |
|
*/ |
|
updateComponent: function (transaction, prevElement, nextElement, context) { |
|
var lastProps = prevElement.props; |
|
var nextProps = this._currentElement.props; |
|
|
|
switch (this._tag) { |
|
case 'input': |
|
lastProps = ReactDOMInput.getHostProps(this, lastProps); |
|
nextProps = ReactDOMInput.getHostProps(this, nextProps); |
|
break; |
|
case 'option': |
|
lastProps = ReactDOMOption.getHostProps(this, lastProps); |
|
nextProps = ReactDOMOption.getHostProps(this, nextProps); |
|
break; |
|
case 'select': |
|
lastProps = ReactDOMSelect.getHostProps(this, lastProps); |
|
nextProps = ReactDOMSelect.getHostProps(this, nextProps); |
|
break; |
|
case 'textarea': |
|
lastProps = ReactDOMTextarea.getHostProps(this, lastProps); |
|
nextProps = ReactDOMTextarea.getHostProps(this, nextProps); |
|
break; |
|
} |
|
|
|
assertValidProps(this, nextProps); |
|
this._updateDOMProperties(lastProps, nextProps, transaction); |
|
this._updateDOMChildren(lastProps, nextProps, transaction, context); |
|
|
|
switch (this._tag) { |
|
case 'input': |
|
// Update the wrapper around inputs *after* updating props. This has to |
|
// happen after `_updateDOMProperties`. Otherwise HTML5 input validations |
|
// raise warnings and prevent the new value from being assigned. |
|
ReactDOMInput.updateWrapper(this); |
|
break; |
|
case 'textarea': |
|
ReactDOMTextarea.updateWrapper(this); |
|
break; |
|
case 'select': |
|
// <select> value update needs to occur after <option> children |
|
// reconciliation |
|
transaction.getReactMountReady().enqueue(postUpdateSelectWrapper, this); |
|
break; |
|
} |
|
}, |
|
|
|
/** |
|
* 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 {object} nextProps |
|
* @param {?DOMElement} node |
|
*/ |
|
_updateDOMProperties: function (lastProps, nextProps, transaction) { |
|
var propKey; |
|
var styleName; |
|
var styleUpdates; |
|
for (propKey in lastProps) { |
|
if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) { |
|
continue; |
|
} |
|
if (propKey === STYLE) { |
|
var lastStyle = this._previousStyleCopy; |
|
for (styleName in lastStyle) { |
|
if (lastStyle.hasOwnProperty(styleName)) { |
|
styleUpdates = styleUpdates || {}; |
|
styleUpdates[styleName] = ''; |
|
} |
|
} |
|
this._previousStyleCopy = null; |
|
} else if (registrationNameModules.hasOwnProperty(propKey)) { |
|
if (lastProps[propKey]) { |
|
// Only call deleteListener if there was a listener previously or |
|
// else willDeleteListener gets called when there wasn't actually a |
|
// listener (e.g., onClick={null}) |
|
deleteListener(this, propKey); |
|
} |
|
} else if (isCustomComponent(this._tag, lastProps)) { |
|
if (!RESERVED_PROPS.hasOwnProperty(propKey)) { |
|
DOMPropertyOperations.deleteValueForAttribute(getNode(this), propKey); |
|
} |
|
} else if (DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) { |
|
DOMPropertyOperations.deleteValueForProperty(getNode(this), propKey); |
|
} |
|
} |
|
for (propKey in nextProps) { |
|
var nextProp = nextProps[propKey]; |
|
var lastProp = propKey === STYLE ? this._previousStyleCopy : lastProps != null ? lastProps[propKey] : undefined; |
|
if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) { |
|
continue; |
|
} |
|
if (propKey === STYLE) { |
|
if (nextProp) { |
|
if ("development" !== 'production') { |
|
checkAndWarnForMutatedStyle(this._previousStyleCopy, this._previousStyle, this); |
|
this._previousStyle = nextProp; |
|
} |
|
nextProp = this._previousStyleCopy = _assign({}, nextProp); |
|
} else { |
|
this._previousStyleCopy = null; |
|
} |
|
if (lastProp) { |
|
// Unset styles on `lastProp` but not on `nextProp`. |
|
for (styleName in lastProp) { |
|
if (lastProp.hasOwnProperty(styleName) && (!nextProp || !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.hasOwnProperty(propKey)) { |
|
if (nextProp) { |
|
enqueuePutListener(this, propKey, nextProp, transaction); |
|
} else if (lastProp) { |
|
deleteListener(this, propKey); |
|
} |
|
} else if (isCustomComponent(this._tag, nextProps)) { |
|
if (!RESERVED_PROPS.hasOwnProperty(propKey)) { |
|
DOMPropertyOperations.setValueForAttribute(getNode(this), propKey, nextProp); |
|
} |
|
} else if (DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) { |
|
var node = getNode(this); |
|
// If we're updating to null or undefined, we should remove the property |
|
// from the DOM node instead of inadvertently setting to a string. This |
|
// brings us in line with the same behavior we have on initial render. |
|
if (nextProp != null) { |
|
DOMPropertyOperations.setValueForProperty(node, propKey, nextProp); |
|
} else { |
|
DOMPropertyOperations.deleteValueForProperty(node, propKey); |
|
} |
|
} |
|
} |
|
if (styleUpdates) { |
|
CSSPropertyOperations.setValueForStyles(getNode(this), styleUpdates, this); |
|
} |
|
}, |
|
|
|
/** |
|
* Reconciles the children with the various properties that affect the |
|
* children content. |
|
* |
|
* @param {object} lastProps |
|
* @param {object} nextProps |
|
* @param {ReactReconcileTransaction} transaction |
|
* @param {object} context |
|
*/ |
|
_updateDOMChildren: function (lastProps, nextProps, transaction, context) { |
|
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, context); |
|
} else if (lastHasContentOrHtml && !nextHasContentOrHtml) { |
|
this.updateTextContent(''); |
|
if ("development" !== 'production') { |
|
ReactInstrumentation.debugTool.onSetChildren(this._debugID, []); |
|
} |
|
} |
|
|
|
if (nextContent != null) { |
|
if (lastContent !== nextContent) { |
|
this.updateTextContent('' + nextContent); |
|
if ("development" !== 'production') { |
|
setAndValidateContentChildDev.call(this, nextContent); |
|
} |
|
} |
|
} else if (nextHtml != null) { |
|
if (lastHtml !== nextHtml) { |
|
this.updateMarkup('' + nextHtml); |
|
} |
|
if ("development" !== 'production') { |
|
ReactInstrumentation.debugTool.onSetChildren(this._debugID, []); |
|
} |
|
} else if (nextChildren != null) { |
|
if ("development" !== 'production') { |
|
setAndValidateContentChildDev.call(this, null); |
|
} |
|
|
|
this.updateChildren(nextChildren, transaction, context); |
|
} |
|
}, |
|
|
|
getHostNode: function () { |
|
return getNode(this); |
|
}, |
|
|
|
/** |
|
* Destroys all event registrations for this instance. Does not remove from |
|
* the DOM. That must be done by the parent. |
|
* |
|
* @internal |
|
*/ |
|
unmountComponent: function (safely) { |
|
switch (this._tag) { |
|
case 'audio': |
|
case 'form': |
|
case 'iframe': |
|
case 'img': |
|
case 'link': |
|
case 'object': |
|
case 'source': |
|
case 'video': |
|
var listeners = this._wrapperState.listeners; |
|
if (listeners) { |
|
for (var i = 0; i < listeners.length; i++) { |
|
listeners[i].remove(); |
|
} |
|
} |
|
break; |
|
case 'html': |
|
case 'head': |
|
case 'body': |
|
/** |
|
* 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. |
|
*/ |
|
!false ? "development" !== 'production' ? 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._tag) : _prodInvariant('66', this._tag) : void 0; |
|
break; |
|
} |
|
|
|
this.unmountChildren(safely); |
|
ReactDOMComponentTree.uncacheNode(this); |
|
EventPluginHub.deleteAllListeners(this); |
|
this._rootNodeID = 0; |
|
this._domID = 0; |
|
this._wrapperState = null; |
|
|
|
if ("development" !== 'production') { |
|
setAndValidateContentChildDev.call(this, null); |
|
} |
|
}, |
|
|
|
getPublicInstance: function () { |
|
return getNode(this); |
|
} |
|
|
|
}; |
|
|
|
_assign(ReactDOMComponent.prototype, ReactDOMComponent.Mixin, ReactMultiChild.Mixin); |
|
|
|
module.exports = ReactDOMComponent; |
|
},{"10":10,"107":107,"11":11,"12":12,"122":122,"125":125,"131":131,"142":142,"150":150,"156":156,"157":157,"158":158,"17":17,"18":18,"2":2,"26":26,"33":33,"34":34,"39":39,"42":42,"43":43,"46":46,"5":5,"64":64,"68":68,"77":77,"9":9}],33:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2015-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var ReactDOMComponentFlags = { |
|
hasCachedChildNodes: 1 << 0 |
|
}; |
|
|
|
module.exports = ReactDOMComponentFlags; |
|
},{}],34:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125); |
|
|
|
var DOMProperty = _dereq_(11); |
|
var ReactDOMComponentFlags = _dereq_(33); |
|
|
|
var invariant = _dereq_(150); |
|
|
|
var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME; |
|
var Flags = ReactDOMComponentFlags; |
|
|
|
var internalInstanceKey = '__reactInternalInstance$' + Math.random().toString(36).slice(2); |
|
|
|
/** |
|
* Check if a given node should be cached. |
|
*/ |
|
function shouldPrecacheNode(node, nodeID) { |
|
return node.nodeType === 1 && node.getAttribute(ATTR_NAME) === String(nodeID) || node.nodeType === 8 && node.nodeValue === ' react-text: ' + nodeID + ' ' || node.nodeType === 8 && node.nodeValue === ' react-empty: ' + nodeID + ' '; |
|
} |
|
|
|
/** |
|
* Drill down (through composites and empty components) until we get a host or |
|
* host text component. |
|
* |
|
* This is pretty polymorphic but unavoidable with the current structure we have |
|
* for `_renderedChildren`. |
|
*/ |
|
function getRenderedHostOrTextFromComponent(component) { |
|
var rendered; |
|
while (rendered = component._renderedComponent) { |
|
component = rendered; |
|
} |
|
return component; |
|
} |
|
|
|
/** |
|
* Populate `_hostNode` on the rendered host/text component with the given |
|
* DOM node. The passed `inst` can be a composite. |
|
*/ |
|
function precacheNode(inst, node) { |
|
var hostInst = getRenderedHostOrTextFromComponent(inst); |
|
hostInst._hostNode = node; |
|
node[internalInstanceKey] = hostInst; |
|
} |
|
|
|
function uncacheNode(inst) { |
|
var node = inst._hostNode; |
|
if (node) { |
|
delete node[internalInstanceKey]; |
|
inst._hostNode = null; |
|
} |
|
} |
|
|
|
/** |
|
* Populate `_hostNode` on each child of `inst`, assuming that the children |
|
* match up with the DOM (element) children of `node`. |
|
* |
|
* We cache entire levels at once to avoid an n^2 problem where we access the |
|
* children of a node sequentially and have to walk from the start to our target |
|
* node every time. |
|
* |
|
* Since we update `_renderedChildren` and the actual DOM at (slightly) |
|
* different times, we could race here and see a newer `_renderedChildren` than |
|
* the DOM nodes we see. To avoid this, ReactMultiChild calls |
|
* `prepareToManageChildren` before we change `_renderedChildren`, at which |
|
* time the container's child nodes are always cached (until it unmounts). |
|
*/ |
|
function precacheChildNodes(inst, node) { |
|
if (inst._flags & Flags.hasCachedChildNodes) { |
|
return; |
|
} |
|
var children = inst._renderedChildren; |
|
var childNode = node.firstChild; |
|
outer: for (var name in children) { |
|
if (!children.hasOwnProperty(name)) { |
|
continue; |
|
} |
|
var childInst = children[name]; |
|
var childID = getRenderedHostOrTextFromComponent(childInst)._domID; |
|
if (childID === 0) { |
|
// We're currently unmounting this child in ReactMultiChild; skip it. |
|
continue; |
|
} |
|
// We assume the child nodes are in the same order as the child instances. |
|
for (; childNode !== null; childNode = childNode.nextSibling) { |
|
if (shouldPrecacheNode(childNode, childID)) { |
|
precacheNode(childInst, childNode); |
|
continue outer; |
|
} |
|
} |
|
// We reached the end of the DOM children without finding an ID match. |
|
!false ? "development" !== 'production' ? invariant(false, 'Unable to find element with ID %s.', childID) : _prodInvariant('32', childID) : void 0; |
|
} |
|
inst._flags |= Flags.hasCachedChildNodes; |
|
} |
|
|
|
/** |
|
* Given a DOM node, return the closest ReactDOMComponent or |
|
* ReactDOMTextComponent instance ancestor. |
|
*/ |
|
function getClosestInstanceFromNode(node) { |
|
if (node[internalInstanceKey]) { |
|
return node[internalInstanceKey]; |
|
} |
|
|
|
// Walk up the tree until we find an ancestor whose instance we have cached. |
|
var parents = []; |
|
while (!node[internalInstanceKey]) { |
|
parents.push(node); |
|
if (node.parentNode) { |
|
node = node.parentNode; |
|
} else { |
|
// Top of the tree. This node must not be part of a React tree (or is |
|
// unmounted, potentially). |
|
return null; |
|
} |
|
} |
|
|
|
var closest; |
|
var inst; |
|
for (; node && (inst = node[internalInstanceKey]); node = parents.pop()) { |
|
closest = inst; |
|
if (parents.length) { |
|
precacheChildNodes(inst, node); |
|
} |
|
} |
|
|
|
return closest; |
|
} |
|
|
|
/** |
|
* Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent |
|
* instance, or null if the node was not rendered by this React. |
|
*/ |
|
function getInstanceFromNode(node) { |
|
var inst = getClosestInstanceFromNode(node); |
|
if (inst != null && inst._hostNode === node) { |
|
return inst; |
|
} else { |
|
return null; |
|
} |
|
} |
|
|
|
/** |
|
* Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding |
|
* DOM node. |
|
*/ |
|
function getNodeFromInstance(inst) { |
|
// Without this first invariant, passing a non-DOM-component triggers the next |
|
// invariant for a missing parent, which is super confusing. |
|
!(inst._hostNode !== undefined) ? "development" !== 'production' ? invariant(false, 'getNodeFromInstance: Invalid argument.') : _prodInvariant('33') : void 0; |
|
|
|
if (inst._hostNode) { |
|
return inst._hostNode; |
|
} |
|
|
|
// Walk up the tree until we find an ancestor whose DOM node we have cached. |
|
var parents = []; |
|
while (!inst._hostNode) { |
|
parents.push(inst); |
|
!inst._hostParent ? "development" !== 'production' ? invariant(false, 'React DOM tree root should always have a node reference.') : _prodInvariant('34') : void 0; |
|
inst = inst._hostParent; |
|
} |
|
|
|
// Now parents contains each ancestor that does *not* have a cached native |
|
// node, and `inst` is the deepest ancestor that does. |
|
for (; parents.length; inst = parents.pop()) { |
|
precacheChildNodes(inst, inst._hostNode); |
|
} |
|
|
|
return inst._hostNode; |
|
} |
|
|
|
var ReactDOMComponentTree = { |
|
getClosestInstanceFromNode: getClosestInstanceFromNode, |
|
getInstanceFromNode: getInstanceFromNode, |
|
getNodeFromInstance: getNodeFromInstance, |
|
precacheChildNodes: precacheChildNodes, |
|
precacheNode: precacheNode, |
|
uncacheNode: uncacheNode |
|
}; |
|
|
|
module.exports = ReactDOMComponentTree; |
|
},{"11":11,"125":125,"150":150,"33":33}],35:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var validateDOMNesting = _dereq_(131); |
|
|
|
var DOC_NODE_TYPE = 9; |
|
|
|
function ReactDOMContainerInfo(topLevelWrapper, node) { |
|
var info = { |
|
_topLevelWrapper: topLevelWrapper, |
|
_idCounter: 1, |
|
_ownerDocument: node ? node.nodeType === DOC_NODE_TYPE ? node : node.ownerDocument : null, |
|
_node: node, |
|
_tag: node ? node.nodeName.toLowerCase() : null, |
|
_namespaceURI: node ? node.namespaceURI : null |
|
}; |
|
if ("development" !== 'production') { |
|
info._ancestorInfo = node ? validateDOMNesting.updatedAncestorInfo(null, info._tag, null) : null; |
|
} |
|
return info; |
|
} |
|
|
|
module.exports = ReactDOMContainerInfo; |
|
},{"131":131}],36:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2014-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _assign = _dereq_(158); |
|
|
|
var DOMLazyTree = _dereq_(9); |
|
var ReactDOMComponentTree = _dereq_(34); |
|
|
|
var ReactDOMEmptyComponent = function (instantiate) { |
|
// ReactCompositeComponent uses this: |
|
this._currentElement = null; |
|
// ReactDOMComponentTree uses these: |
|
this._hostNode = null; |
|
this._hostParent = null; |
|
this._hostContainerInfo = null; |
|
this._domID = 0; |
|
}; |
|
_assign(ReactDOMEmptyComponent.prototype, { |
|
mountComponent: function (transaction, hostParent, hostContainerInfo, context) { |
|
var domID = hostContainerInfo._idCounter++; |
|
this._domID = domID; |
|
this._hostParent = hostParent; |
|
this._hostContainerInfo = hostContainerInfo; |
|
|
|
var nodeValue = ' react-empty: ' + this._domID + ' '; |
|
if (transaction.useCreateElement) { |
|
var ownerDocument = hostContainerInfo._ownerDocument; |
|
var node = ownerDocument.createComment(nodeValue); |
|
ReactDOMComponentTree.precacheNode(this, node); |
|
return DOMLazyTree(node); |
|
} else { |
|
if (transaction.renderToStaticMarkup) { |
|
// Normally we'd insert a comment node, but since this is a situation |
|
// where React won't take over (static pages), we can simply return |
|
// nothing. |
|
return ''; |
|
} |
|
return '<!--' + nodeValue + '-->'; |
|
} |
|
}, |
|
receiveComponent: function () {}, |
|
getHostNode: function () { |
|
return ReactDOMComponentTree.getNodeFromInstance(this); |
|
}, |
|
unmountComponent: function () { |
|
ReactDOMComponentTree.uncacheNode(this); |
|
} |
|
}); |
|
|
|
module.exports = ReactDOMEmptyComponent; |
|
},{"158":158,"34":34,"9":9}],37:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var ReactDOMFeatureFlags = { |
|
useCreateElement: true, |
|
useFiber: false |
|
}; |
|
|
|
module.exports = ReactDOMFeatureFlags; |
|
},{}],38:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var DOMChildrenOperations = _dereq_(8); |
|
var ReactDOMComponentTree = _dereq_(34); |
|
|
|
/** |
|
* Operations used to process updates to DOM nodes. |
|
*/ |
|
var ReactDOMIDOperations = { |
|
|
|
/** |
|
* Updates a component's children by processing a series of updates. |
|
* |
|
* @param {array<object>} updates List of update configurations. |
|
* @internal |
|
*/ |
|
dangerouslyProcessChildrenUpdates: function (parentInst, updates) { |
|
var node = ReactDOMComponentTree.getNodeFromInstance(parentInst); |
|
DOMChildrenOperations.processUpdates(node, updates); |
|
} |
|
}; |
|
|
|
module.exports = ReactDOMIDOperations; |
|
},{"34":34,"8":8}],39:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125), |
|
_assign = _dereq_(158); |
|
|
|
var DOMPropertyOperations = _dereq_(12); |
|
var LinkedValueUtils = _dereq_(24); |
|
var ReactDOMComponentTree = _dereq_(34); |
|
var ReactUpdates = _dereq_(82); |
|
|
|
var invariant = _dereq_(150); |
|
var warning = _dereq_(157); |
|
|
|
var didWarnValueLink = false; |
|
var didWarnCheckedLink = false; |
|
var didWarnValueDefaultValue = false; |
|
var didWarnCheckedDefaultChecked = false; |
|
var didWarnControlledToUncontrolled = false; |
|
var didWarnUncontrolledToControlled = false; |
|
|
|
function forceUpdateIfMounted() { |
|
if (this._rootNodeID) { |
|
// DOM component is still mounted; update |
|
ReactDOMInput.updateWrapper(this); |
|
} |
|
} |
|
|
|
function isControlled(props) { |
|
var usesChecked = props.type === 'checkbox' || props.type === 'radio'; |
|
return usesChecked ? props.checked != null : props.value != null; |
|
} |
|
|
|
/** |
|
* Implements an <input> host 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 = { |
|
getHostProps: function (inst, props) { |
|
var value = LinkedValueUtils.getValue(props); |
|
var checked = LinkedValueUtils.getChecked(props); |
|
|
|
var hostProps = _assign({ |
|
// Make sure we set .type before any other properties (setting .value |
|
// before .type means .value is lost in IE11 and below) |
|
type: undefined, |
|
// Make sure we set .step before .value (setting .value before .step |
|
// means .value is rounded on mount, based upon step precision) |
|
step: undefined, |
|
// Make sure we set .min & .max before .value (to ensure proper order |
|
// in corner cases such as min or max deriving from value, e.g. Issue #7170) |
|
min: undefined, |
|
max: undefined |
|
}, props, { |
|
defaultChecked: undefined, |
|
defaultValue: undefined, |
|
value: value != null ? value : inst._wrapperState.initialValue, |
|
checked: checked != null ? checked : inst._wrapperState.initialChecked, |
|
onChange: inst._wrapperState.onChange |
|
}); |
|
|
|
return hostProps; |
|
}, |
|
|
|
mountWrapper: function (inst, props) { |
|
if ("development" !== 'production') { |
|
LinkedValueUtils.checkPropTypes('input', props, inst._currentElement._owner); |
|
|
|
var owner = inst._currentElement._owner; |
|
|
|
if (props.valueLink !== undefined && !didWarnValueLink) { |
|
"development" !== 'production' ? warning(false, '`valueLink` prop on `input` is deprecated; set `value` and `onChange` instead.') : void 0; |
|
didWarnValueLink = true; |
|
} |
|
if (props.checkedLink !== undefined && !didWarnCheckedLink) { |
|
"development" !== 'production' ? warning(false, '`checkedLink` prop on `input` is deprecated; set `value` and `onChange` instead.') : void 0; |
|
didWarnCheckedLink = true; |
|
} |
|
if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) { |
|
"development" !== 'production' ? warning(false, '%s contains an input of type %s with both checked and defaultChecked props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the checked prop, or the defaultChecked prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', owner && owner.getName() || 'A component', props.type) : void 0; |
|
didWarnCheckedDefaultChecked = true; |
|
} |
|
if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) { |
|
"development" !== 'production' ? warning(false, '%s contains an input of type %s with both value and defaultValue props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', owner && owner.getName() || 'A component', props.type) : void 0; |
|
didWarnValueDefaultValue = true; |
|
} |
|
} |
|
|
|
var defaultValue = props.defaultValue; |
|
inst._wrapperState = { |
|
initialChecked: props.checked != null ? props.checked : props.defaultChecked, |
|
initialValue: props.value != null ? props.value : defaultValue, |
|
listeners: null, |
|
onChange: _handleChange.bind(inst) |
|
}; |
|
|
|
if ("development" !== 'production') { |
|
inst._wrapperState.controlled = isControlled(props); |
|
} |
|
}, |
|
|
|
updateWrapper: function (inst) { |
|
var props = inst._currentElement.props; |
|
|
|
if ("development" !== 'production') { |
|
var controlled = isControlled(props); |
|
var owner = inst._currentElement._owner; |
|
|
|
if (!inst._wrapperState.controlled && controlled && !didWarnUncontrolledToControlled) { |
|
"development" !== 'production' ? warning(false, '%s is changing an uncontrolled input of type %s to be controlled. ' + 'Input elements should not switch from uncontrolled to controlled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', owner && owner.getName() || 'A component', props.type) : void 0; |
|
didWarnUncontrolledToControlled = true; |
|
} |
|
if (inst._wrapperState.controlled && !controlled && !didWarnControlledToUncontrolled) { |
|
"development" !== 'production' ? warning(false, '%s is changing a controlled input of type %s to be uncontrolled. ' + 'Input elements should not switch from controlled to uncontrolled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', owner && owner.getName() || 'A component', props.type) : void 0; |
|
didWarnControlledToUncontrolled = true; |
|
} |
|
} |
|
|
|
// TODO: Shouldn't this be getChecked(props)? |
|
var checked = props.checked; |
|
if (checked != null) { |
|
DOMPropertyOperations.setValueForProperty(ReactDOMComponentTree.getNodeFromInstance(inst), 'checked', checked || false); |
|
} |
|
|
|
var node = ReactDOMComponentTree.getNodeFromInstance(inst); |
|
var value = LinkedValueUtils.getValue(props); |
|
if (value != null) { |
|
|
|
// Cast `value` to a string to ensure the value is set correctly. While |
|
// browsers typically do this as necessary, jsdom doesn't. |
|
var newValue = '' + value; |
|
|
|
// To avoid side effects (such as losing text selection), only set value if changed |
|
if (newValue !== node.value) { |
|
node.value = newValue; |
|
} |
|
} else { |
|
if (props.value == null && props.defaultValue != null) { |
|
// In Chrome, assigning defaultValue to certain input types triggers input validation. |
|
// For number inputs, the display value loses trailing decimal points. For email inputs, |
|
// Chrome raises "The specified value <x> is not a valid email address". |
|
// |
|
// Here we check to see if the defaultValue has actually changed, avoiding these problems |
|
// when the user is inputting text |
|
// |
|
// https://github.com/facebook/react/issues/7253 |
|
if (node.defaultValue !== '' + props.defaultValue) { |
|
node.defaultValue = '' + props.defaultValue; |
|
} |
|
} |
|
if (props.checked == null && props.defaultChecked != null) { |
|
node.defaultChecked = !!props.defaultChecked; |
|
} |
|
} |
|
}, |
|
|
|
postMountWrapper: function (inst) { |
|
var props = inst._currentElement.props; |
|
|
|
// This is in postMount because we need access to the DOM node, which is not |
|
// available until after the component has mounted. |
|
var node = ReactDOMComponentTree.getNodeFromInstance(inst); |
|
|
|
// Detach value from defaultValue. We won't do anything if we're working on |
|
// submit or reset inputs as those values & defaultValues are linked. They |
|
// are not resetable nodes so this operation doesn't matter and actually |
|
// removes browser-default values (eg "Submit Query") when no value is |
|
// provided. |
|
|
|
switch (props.type) { |
|
case 'submit': |
|
case 'reset': |
|
break; |
|
case 'color': |
|
case 'date': |
|
case 'datetime': |
|
case 'datetime-local': |
|
case 'month': |
|
case 'time': |
|
case 'week': |
|
// This fixes the no-show issue on iOS Safari and Android Chrome: |
|
// https://github.com/facebook/react/issues/7233 |
|
node.value = ''; |
|
node.value = node.defaultValue; |
|
break; |
|
default: |
|
node.value = node.value; |
|
break; |
|
} |
|
|
|
// Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug |
|
// this is needed to work around a chrome bug where setting defaultChecked |
|
// will sometimes influence the value of checked (even after detachment). |
|
// Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416 |
|
// We need to temporarily unset name to avoid disrupting radio button groups. |
|
var name = node.name; |
|
if (name !== '') { |
|
node.name = ''; |
|
} |
|
node.defaultChecked = !node.defaultChecked; |
|
node.defaultChecked = !node.defaultChecked; |
|
if (name !== '') { |
|
node.name = name; |
|
} |
|
} |
|
}; |
|
|
|
function _handleChange(event) { |
|
var props = this._currentElement.props; |
|
|
|
var returnValue = LinkedValueUtils.executeOnChange(props, event); |
|
|
|
// Here we use asap to wait until all updates have propagated, which |
|
// is important when using controlled components within layers: |
|
// https://github.com/facebook/react/issues/1698 |
|
ReactUpdates.asap(forceUpdateIfMounted, this); |
|
|
|
var name = props.name; |
|
if (props.type === 'radio' && name != null) { |
|
var rootNode = ReactDOMComponentTree.getNodeFromInstance(this); |
|
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; i < group.length; i++) { |
|
var otherNode = group[i]; |
|
if (otherNode === rootNode || otherNode.form !== rootNode.form) { |
|
continue; |
|
} |
|
// This will throw if radio buttons rendered by different copies of React |
|
// and the same name are rendered into the same form (same as #1939). |
|
// That's probably okay; we don't support it just as we don't support |
|
// mixing React radio buttons with non-React ones. |
|
var otherInstance = ReactDOMComponentTree.getInstanceFromNode(otherNode); |
|
!otherInstance ? "development" !== 'production' ? invariant(false, 'ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported.') : _prodInvariant('90') : void 0; |
|
// If this is a controlled radio button group, forcing the input that |
|
// was previously checked to update will cause it to be come re-checked |
|
// as appropriate. |
|
ReactUpdates.asap(forceUpdateIfMounted, otherInstance); |
|
} |
|
} |
|
|
|
return returnValue; |
|
} |
|
|
|
module.exports = ReactDOMInput; |
|
},{"12":12,"125":125,"150":150,"157":157,"158":158,"24":24,"34":34,"82":82}],40:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var DOMProperty = _dereq_(11); |
|
var ReactComponentTreeHook = _dereq_(132); |
|
|
|
var warning = _dereq_(157); |
|
|
|
var warnedProperties = {}; |
|
var rARIA = new RegExp('^(aria)-[' + DOMProperty.ATTRIBUTE_NAME_CHAR + ']*$'); |
|
|
|
function validateProperty(tagName, name, debugID) { |
|
if (warnedProperties.hasOwnProperty(name) && warnedProperties[name]) { |
|
return true; |
|
} |
|
|
|
if (rARIA.test(name)) { |
|
var lowerCasedName = name.toLowerCase(); |
|
var standardName = DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? DOMProperty.getPossibleStandardName[lowerCasedName] : null; |
|
|
|
// If this is an aria-* attribute, but is not listed in the known DOM |
|
// DOM properties, then it is an invalid aria-* attribute. |
|
if (standardName == null) { |
|
warnedProperties[name] = true; |
|
return false; |
|
} |
|
// aria-* attributes should be lowercase; suggest the lowercase version. |
|
if (name !== standardName) { |
|
"development" !== 'production' ? warning(false, 'Unknown ARIA attribute %s. Did you mean %s?%s', name, standardName, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0; |
|
warnedProperties[name] = true; |
|
return true; |
|
} |
|
} |
|
|
|
return true; |
|
} |
|
|
|
function warnInvalidARIAProps(debugID, element) { |
|
var invalidProps = []; |
|
|
|
for (var key in element.props) { |
|
var isValid = validateProperty(element.type, key, debugID); |
|
if (!isValid) { |
|
invalidProps.push(key); |
|
} |
|
} |
|
|
|
var unknownPropString = invalidProps.map(function (prop) { |
|
return '`' + prop + '`'; |
|
}).join(', '); |
|
|
|
if (invalidProps.length === 1) { |
|
"development" !== 'production' ? warning(false, 'Invalid aria prop %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop%s', unknownPropString, element.type, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0; |
|
} else if (invalidProps.length > 1) { |
|
"development" !== 'production' ? warning(false, 'Invalid aria props %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop%s', unknownPropString, element.type, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0; |
|
} |
|
} |
|
|
|
function handleElement(debugID, element) { |
|
if (element == null || typeof element.type !== 'string') { |
|
return; |
|
} |
|
if (element.type.indexOf('-') >= 0 || element.props.is) { |
|
return; |
|
} |
|
|
|
warnInvalidARIAProps(debugID, element); |
|
} |
|
|
|
var ReactDOMInvalidARIAHook = { |
|
onBeforeMountComponent: function (debugID, element) { |
|
if ("development" !== 'production') { |
|
handleElement(debugID, element); |
|
} |
|
}, |
|
onBeforeUpdateComponent: function (debugID, element) { |
|
if ("development" !== 'production') { |
|
handleElement(debugID, element); |
|
} |
|
} |
|
}; |
|
|
|
module.exports = ReactDOMInvalidARIAHook; |
|
},{"11":11,"132":132,"157":157}],41:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var ReactComponentTreeHook = _dereq_(132); |
|
|
|
var warning = _dereq_(157); |
|
|
|
var didWarnValueNull = false; |
|
|
|
function handleElement(debugID, element) { |
|
if (element == null) { |
|
return; |
|
} |
|
if (element.type !== 'input' && element.type !== 'textarea' && element.type !== 'select') { |
|
return; |
|
} |
|
if (element.props != null && element.props.value === null && !didWarnValueNull) { |
|
"development" !== 'production' ? warning(false, '`value` prop on `%s` should not be null. ' + 'Consider using the empty string to clear the component or `undefined` ' + 'for uncontrolled components.%s', element.type, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0; |
|
|
|
didWarnValueNull = true; |
|
} |
|
} |
|
|
|
var ReactDOMNullInputValuePropHook = { |
|
onBeforeMountComponent: function (debugID, element) { |
|
handleElement(debugID, element); |
|
}, |
|
onBeforeUpdateComponent: function (debugID, element) { |
|
handleElement(debugID, element); |
|
} |
|
}; |
|
|
|
module.exports = ReactDOMNullInputValuePropHook; |
|
},{"132":132,"157":157}],42:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _assign = _dereq_(158); |
|
|
|
var React = _dereq_(134); |
|
var ReactDOMComponentTree = _dereq_(34); |
|
var ReactDOMSelect = _dereq_(43); |
|
|
|
var warning = _dereq_(157); |
|
var didWarnInvalidOptionChildren = false; |
|
|
|
function flattenChildren(children) { |
|
var content = ''; |
|
|
|
// Flatten children and warn if they aren't strings or numbers; |
|
// invalid types are ignored. |
|
React.Children.forEach(children, function (child) { |
|
if (child == null) { |
|
return; |
|
} |
|
if (typeof child === 'string' || typeof child === 'number') { |
|
content += child; |
|
} else if (!didWarnInvalidOptionChildren) { |
|
didWarnInvalidOptionChildren = true; |
|
"development" !== 'production' ? warning(false, 'Only strings and numbers are supported as <option> children.') : void 0; |
|
} |
|
}); |
|
|
|
return content; |
|
} |
|
|
|
/** |
|
* Implements an <option> host component that warns when `selected` is set. |
|
*/ |
|
var ReactDOMOption = { |
|
mountWrapper: function (inst, props, hostParent) { |
|
// TODO (yungsters): Remove support for `selected` in <option>. |
|
if ("development" !== 'production') { |
|
"development" !== 'production' ? warning(props.selected == null, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.') : void 0; |
|
} |
|
|
|
// Look up whether this option is 'selected' |
|
var selectValue = null; |
|
if (hostParent != null) { |
|
var selectParent = hostParent; |
|
|
|
if (selectParent._tag === 'optgroup') { |
|
selectParent = selectParent._hostParent; |
|
} |
|
|
|
if (selectParent != null && selectParent._tag === 'select') { |
|
selectValue = ReactDOMSelect.getSelectValueContext(selectParent); |
|
} |
|
} |
|
|
|
// If the value is null (e.g., no specified value or after initial mount) |
|
// or missing (e.g., for <datalist>), we don't change props.selected |
|
var selected = null; |
|
if (selectValue != null) { |
|
var value; |
|
if (props.value != null) { |
|
value = props.value + ''; |
|
} else { |
|
value = flattenChildren(props.children); |
|
} |
|
selected = false; |
|
if (Array.isArray(selectValue)) { |
|
// multiple |
|
for (var i = 0; i < selectValue.length; i++) { |
|
if ('' + selectValue[i] === value) { |
|
selected = true; |
|
break; |
|
} |
|
} |
|
} else { |
|
selected = '' + selectValue === value; |
|
} |
|
} |
|
|
|
inst._wrapperState = { selected: selected }; |
|
}, |
|
|
|
postMountWrapper: function (inst) { |
|
// value="" should make a value attribute (#6219) |
|
var props = inst._currentElement.props; |
|
if (props.value != null) { |
|
var node = ReactDOMComponentTree.getNodeFromInstance(inst); |
|
node.setAttribute('value', props.value); |
|
} |
|
}, |
|
|
|
getHostProps: function (inst, props) { |
|
var hostProps = _assign({ selected: undefined, children: undefined }, props); |
|
|
|
// Read state only from initial mount because <select> updates value |
|
// manually; we need the initial state only for server rendering |
|
if (inst._wrapperState.selected != null) { |
|
hostProps.selected = inst._wrapperState.selected; |
|
} |
|
|
|
var content = flattenChildren(props.children); |
|
|
|
if (content) { |
|
hostProps.children = content; |
|
} |
|
|
|
return hostProps; |
|
} |
|
|
|
}; |
|
|
|
module.exports = ReactDOMOption; |
|
},{"134":134,"157":157,"158":158,"34":34,"43":43}],43:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _assign = _dereq_(158); |
|
|
|
var LinkedValueUtils = _dereq_(24); |
|
var ReactDOMComponentTree = _dereq_(34); |
|
var ReactUpdates = _dereq_(82); |
|
|
|
var warning = _dereq_(157); |
|
|
|
var didWarnValueLink = false; |
|
var didWarnValueDefaultValue = false; |
|
|
|
function updateOptionsIfPendingUpdateAndMounted() { |
|
if (this._rootNodeID && this._wrapperState.pendingUpdate) { |
|
this._wrapperState.pendingUpdate = false; |
|
|
|
var props = this._currentElement.props; |
|
var value = LinkedValueUtils.getValue(props); |
|
|
|
if (value != null) { |
|
updateOptions(this, Boolean(props.multiple), value); |
|
} |
|
} |
|
} |
|
|
|
function getDeclarationErrorAddendum(owner) { |
|
if (owner) { |
|
var name = owner.getName(); |
|
if (name) { |
|
return ' Check the render method of `' + name + '`.'; |
|
} |
|
} |
|
return ''; |
|
} |
|
|
|
var valuePropNames = ['value', 'defaultValue']; |
|
|
|
/** |
|
* Validation function for `value` and `defaultValue`. |
|
* @private |
|
*/ |
|
function checkSelectPropTypes(inst, props) { |
|
var owner = inst._currentElement._owner; |
|
LinkedValueUtils.checkPropTypes('select', props, owner); |
|
|
|
if (props.valueLink !== undefined && !didWarnValueLink) { |
|
"development" !== 'production' ? warning(false, '`valueLink` prop on `select` is deprecated; set `value` and `onChange` instead.') : void 0; |
|
didWarnValueLink = true; |
|
} |
|
|
|
for (var i = 0; i < valuePropNames.length; i++) { |
|
var propName = valuePropNames[i]; |
|
if (props[propName] == null) { |
|
continue; |
|
} |
|
var isArray = Array.isArray(props[propName]); |
|
if (props.multiple && !isArray) { |
|
"development" !== 'production' ? warning(false, 'The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum(owner)) : void 0; |
|
} else if (!props.multiple && isArray) { |
|
"development" !== 'production' ? warning(false, 'The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum(owner)) : void 0; |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* @param {ReactDOMComponent} inst |
|
* @param {boolean} multiple |
|
* @param {*} propValue A stringable (with `multiple`, a list of stringables). |
|
* @private |
|
*/ |
|
function updateOptions(inst, multiple, propValue) { |
|
var selectedValue, i; |
|
var options = ReactDOMComponentTree.getNodeFromInstance(inst).options; |
|
|
|
if (multiple) { |
|
selectedValue = {}; |
|
for (i = 0; i < propValue.length; i++) { |
|
selectedValue['' + propValue[i]] = true; |
|
} |
|
for (i = 0; i < options.length; i++) { |
|
var selected = selectedValue.hasOwnProperty(options[i].value); |
|
if (options[i].selected !== selected) { |
|
options[i].selected = selected; |
|
} |
|
} |
|
} else { |
|
// Do not set `select.value` as exact behavior isn't consistent across all |
|
// browsers for all cases. |
|
selectedValue = '' + propValue; |
|
for (i = 0; i < options.length; i++) { |
|
if (options[i].value === selectedValue) { |
|
options[i].selected = true; |
|
return; |
|
} |
|
} |
|
if (options.length) { |
|
options[0].selected = true; |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* Implements a <select> host component that allows optionally setting the |
|
* props `value` and `defaultValue`. If `multiple` is false, the prop must be a |
|
* stringable. If `multiple` is true, the prop must be an array of stringables. |
|
* |
|
* 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 = { |
|
getHostProps: function (inst, props) { |
|
return _assign({}, props, { |
|
onChange: inst._wrapperState.onChange, |
|
value: undefined |
|
}); |
|
}, |
|
|
|
mountWrapper: function (inst, props) { |
|
if ("development" !== 'production') { |
|
checkSelectPropTypes(inst, props); |
|
} |
|
|
|
var value = LinkedValueUtils.getValue(props); |
|
inst._wrapperState = { |
|
pendingUpdate: false, |
|
initialValue: value != null ? value : props.defaultValue, |
|
listeners: null, |
|
onChange: _handleChange.bind(inst), |
|
wasMultiple: Boolean(props.multiple) |
|
}; |
|
|
|
if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) { |
|
"development" !== 'production' ? warning(false, 'Select elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled select ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components') : void 0; |
|
didWarnValueDefaultValue = true; |
|
} |
|
}, |
|
|
|
getSelectValueContext: function (inst) { |
|
// ReactDOMOption looks at this initial value so the initial generated |
|
// markup has correct `selected` attributes |
|
return inst._wrapperState.initialValue; |
|
}, |
|
|
|
postUpdateWrapper: function (inst) { |
|
var props = inst._currentElement.props; |
|
|
|
// After the initial mount, we control selected-ness manually so don't pass |
|
// this value down |
|
inst._wrapperState.initialValue = undefined; |
|
|
|
var wasMultiple = inst._wrapperState.wasMultiple; |
|
inst._wrapperState.wasMultiple = Boolean(props.multiple); |
|
|
|
var value = LinkedValueUtils.getValue(props); |
|
if (value != null) { |
|
inst._wrapperState.pendingUpdate = false; |
|
updateOptions(inst, Boolean(props.multiple), value); |
|
} else if (wasMultiple !== Boolean(props.multiple)) { |
|
// For simplicity, reapply `defaultValue` if `multiple` is toggled. |
|
if (props.defaultValue != null) { |
|
updateOptions(inst, Boolean(props.multiple), props.defaultValue); |
|
} else { |
|
// Revert the select back to its default unselected state. |
|
updateOptions(inst, Boolean(props.multiple), props.multiple ? [] : ''); |
|
} |
|
} |
|
} |
|
}; |
|
|
|
function _handleChange(event) { |
|
var props = this._currentElement.props; |
|
var returnValue = LinkedValueUtils.executeOnChange(props, event); |
|
|
|
if (this._rootNodeID) { |
|
this._wrapperState.pendingUpdate = true; |
|
} |
|
ReactUpdates.asap(updateOptionsIfPendingUpdateAndMounted, this); |
|
return returnValue; |
|
} |
|
|
|
module.exports = ReactDOMSelect; |
|
},{"157":157,"158":158,"24":24,"34":34,"82":82}],44:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var ExecutionEnvironment = _dereq_(136); |
|
|
|
var getNodeForCharacterOffset = _dereq_(118); |
|
var getTextContentAccessor = _dereq_(119); |
|
|
|
/** |
|
* While `isCollapsed` is available on the Selection object and `collapsed` |
|
* is available on the Range object, IE11 sometimes gets them wrong. |
|
* If the anchor/focus nodes and offsets are the same, the range is collapsed. |
|
*/ |
|
function isCollapsed(anchorNode, anchorOffset, focusNode, focusOffset) { |
|
return anchorNode === focusNode && anchorOffset === focusOffset; |
|
} |
|
|
|
/** |
|
* 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 && window.getSelection(); |
|
|
|
if (!selection || 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); |
|
|
|
// In Firefox, range.startContainer and range.endContainer can be "anonymous |
|
// divs", e.g. the up/down buttons on an <input type="number">. Anonymous |
|
// divs do not seem to expose properties, triggering a "Permission denied |
|
// error" if any of its properties are accessed. The only seemingly possible |
|
// way to avoid erroring is to access a property that typically works for |
|
// non-anonymous divs and catch any error that may otherwise arise. See |
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=208427 |
|
try { |
|
/* eslint-disable no-unused-expressions */ |
|
currentRange.startContainer.nodeType; |
|
currentRange.endContainer.nodeType; |
|
/* eslint-enable no-unused-expressions */ |
|
} catch (e) { |
|
return null; |
|
} |
|
|
|
// If the node and offset values are the same, the selection is collapsed. |
|
// `Selection.isCollapsed` is available natively, but IE sometimes gets |
|
// this value wrong. |
|
var isSelectionCollapsed = isCollapsed(selection.anchorNode, selection.anchorOffset, selection.focusNode, selection.focusOffset); |
|
|
|
var rangeLength = isSelectionCollapsed ? 0 : currentRange.toString().length; |
|
|
|
var tempRange = currentRange.cloneRange(); |
|
tempRange.selectNodeContents(node); |
|
tempRange.setEnd(currentRange.startContainer, currentRange.startOffset); |
|
|
|
var isTempRangeCollapsed = isCollapsed(tempRange.startContainer, tempRange.startOffset, tempRange.endContainer, tempRange.endOffset); |
|
|
|
var start = isTempRangeCollapsed ? 0 : 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; |
|
|
|
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 (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 programmatically 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) { |
|
if (!window.getSelection) { |
|
return; |
|
} |
|
|
|
var selection = window.getSelection(); |
|
var length = node[getTextContentAccessor()].length; |
|
var start = Math.min(offsets.start, length); |
|
var end = 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); |
|
} |
|
} |
|
} |
|
|
|
var useIEOffsets = ExecutionEnvironment.canUseDOM && 'selection' in document && !('getSelection' in window); |
|
|
|
var ReactDOMSelection = { |
|
/** |
|
* @param {DOMElement} node |
|
*/ |
|
getOffsets: useIEOffsets ? getIEOffsets : getModernOffsets, |
|
|
|
/** |
|
* @param {DOMElement|DOMTextNode} node |
|
* @param {object} offsets |
|
*/ |
|
setOffsets: useIEOffsets ? setIEOffsets : setModernOffsets |
|
}; |
|
|
|
module.exports = ReactDOMSelection; |
|
},{"118":118,"119":119,"136":136}],45:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125), |
|
_assign = _dereq_(158); |
|
|
|
var DOMChildrenOperations = _dereq_(8); |
|
var DOMLazyTree = _dereq_(9); |
|
var ReactDOMComponentTree = _dereq_(34); |
|
|
|
var escapeTextContentForBrowser = _dereq_(107); |
|
var invariant = _dereq_(150); |
|
var validateDOMNesting = _dereq_(131); |
|
|
|
/** |
|
* 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 between comment nodes 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 ReactDOMTextComponent |
|
* @extends ReactComponent |
|
* @internal |
|
*/ |
|
var ReactDOMTextComponent = function (text) { |
|
// TODO: This is really a ReactText (ReactNode), not a ReactElement |
|
this._currentElement = text; |
|
this._stringText = '' + text; |
|
// ReactDOMComponentTree uses these: |
|
this._hostNode = null; |
|
this._hostParent = null; |
|
|
|
// Properties |
|
this._domID = 0; |
|
this._mountIndex = 0; |
|
this._closingComment = null; |
|
this._commentNodes = null; |
|
}; |
|
|
|
_assign(ReactDOMTextComponent.prototype, { |
|
|
|
/** |
|
* Creates the markup for this text node. This node is not intended to have |
|
* any features besides containing text content. |
|
* |
|
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction |
|
* @return {string} Markup for this text node. |
|
* @internal |
|
*/ |
|
mountComponent: function (transaction, hostParent, hostContainerInfo, context) { |
|
if ("development" !== 'production') { |
|
var parentInfo; |
|
if (hostParent != null) { |
|
parentInfo = hostParent._ancestorInfo; |
|
} else if (hostContainerInfo != null) { |
|
parentInfo = hostContainerInfo._ancestorInfo; |
|
} |
|
if (parentInfo) { |
|
// parentInfo should always be present except for the top-level |
|
// component when server rendering |
|
validateDOMNesting(null, this._stringText, this, parentInfo); |
|
} |
|
} |
|
|
|
var domID = hostContainerInfo._idCounter++; |
|
var openingValue = ' react-text: ' + domID + ' '; |
|
var closingValue = ' /react-text '; |
|
this._domID = domID; |
|
this._hostParent = hostParent; |
|
if (transaction.useCreateElement) { |
|
var ownerDocument = hostContainerInfo._ownerDocument; |
|
var openingComment = ownerDocument.createComment(openingValue); |
|
var closingComment = ownerDocument.createComment(closingValue); |
|
var lazyTree = DOMLazyTree(ownerDocument.createDocumentFragment()); |
|
DOMLazyTree.queueChild(lazyTree, DOMLazyTree(openingComment)); |
|
if (this._stringText) { |
|
DOMLazyTree.queueChild(lazyTree, DOMLazyTree(ownerDocument.createTextNode(this._stringText))); |
|
} |
|
DOMLazyTree.queueChild(lazyTree, DOMLazyTree(closingComment)); |
|
ReactDOMComponentTree.precacheNode(this, openingComment); |
|
this._closingComment = closingComment; |
|
return lazyTree; |
|
} else { |
|
var escapedText = escapeTextContentForBrowser(this._stringText); |
|
|
|
if (transaction.renderToStaticMarkup) { |
|
// Normally we'd wrap this between comment nodes 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 '<!--' + openingValue + '-->' + escapedText + '<!--' + closingValue + '-->'; |
|
} |
|
}, |
|
|
|
/** |
|
* Updates this component by updating the text content. |
|
* |
|
* @param {ReactText} nextText The next text content |
|
* @param {ReactReconcileTransaction} transaction |
|
* @internal |
|
*/ |
|
receiveComponent: function (nextText, transaction) { |
|
if (nextText !== this._currentElement) { |
|
this._currentElement = nextText; |
|
var nextStringText = '' + nextText; |
|
if (nextStringText !== this._stringText) { |
|
// TODO: Save this as pending props and use performUpdateIfNecessary |
|
// and/or updateComponent to do the actual update for consistency with |
|
// other component types? |
|
this._stringText = nextStringText; |
|
var commentNodes = this.getHostNode(); |
|
DOMChildrenOperations.replaceDelimitedText(commentNodes[0], commentNodes[1], nextStringText); |
|
} |
|
} |
|
}, |
|
|
|
getHostNode: function () { |
|
var hostNode = this._commentNodes; |
|
if (hostNode) { |
|
return hostNode; |
|
} |
|
if (!this._closingComment) { |
|
var openingComment = ReactDOMComponentTree.getNodeFromInstance(this); |
|
var node = openingComment.nextSibling; |
|
while (true) { |
|
!(node != null) ? "development" !== 'production' ? invariant(false, 'Missing closing comment for text component %s', this._domID) : _prodInvariant('67', this._domID) : void 0; |
|
if (node.nodeType === 8 && node.nodeValue === ' /react-text ') { |
|
this._closingComment = node; |
|
break; |
|
} |
|
node = node.nextSibling; |
|
} |
|
} |
|
hostNode = [this._hostNode, this._closingComment]; |
|
this._commentNodes = hostNode; |
|
return hostNode; |
|
}, |
|
|
|
unmountComponent: function () { |
|
this._closingComment = null; |
|
this._commentNodes = null; |
|
ReactDOMComponentTree.uncacheNode(this); |
|
} |
|
|
|
}); |
|
|
|
module.exports = ReactDOMTextComponent; |
|
},{"107":107,"125":125,"131":131,"150":150,"158":158,"34":34,"8":8,"9":9}],46:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125), |
|
_assign = _dereq_(158); |
|
|
|
var LinkedValueUtils = _dereq_(24); |
|
var ReactDOMComponentTree = _dereq_(34); |
|
var ReactUpdates = _dereq_(82); |
|
|
|
var invariant = _dereq_(150); |
|
var warning = _dereq_(157); |
|
|
|
var didWarnValueLink = false; |
|
var didWarnValDefaultVal = false; |
|
|
|
function forceUpdateIfMounted() { |
|
if (this._rootNodeID) { |
|
// DOM component is still mounted; update |
|
ReactDOMTextarea.updateWrapper(this); |
|
} |
|
} |
|
|
|
/** |
|
* Implements a <textarea> host 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 = { |
|
getHostProps: function (inst, props) { |
|
!(props.dangerouslySetInnerHTML == null) ? "development" !== 'production' ? invariant(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : _prodInvariant('91') : void 0; |
|
|
|
// Always set children to the same thing. In IE9, the selection range will |
|
// get reset if `textContent` is mutated. We could add a check in setTextContent |
|
// to only set the value if/when the value differs from the node value (which would |
|
// completely solve this IE9 bug), but Sebastian+Ben seemed to like this solution. |
|
// The value can be a boolean or object so that's why it's forced to be a string. |
|
var hostProps = _assign({}, props, { |
|
value: undefined, |
|
defaultValue: undefined, |
|
children: '' + inst._wrapperState.initialValue, |
|
onChange: inst._wrapperState.onChange |
|
}); |
|
|
|
return hostProps; |
|
}, |
|
|
|
mountWrapper: function (inst, props) { |
|
if ("development" !== 'production') { |
|
LinkedValueUtils.checkPropTypes('textarea', props, inst._currentElement._owner); |
|
if (props.valueLink !== undefined && !didWarnValueLink) { |
|
"development" !== 'production' ? warning(false, '`valueLink` prop on `textarea` is deprecated; set `value` and `onChange` instead.') : void 0; |
|
didWarnValueLink = true; |
|
} |
|
if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) { |
|
"development" !== 'production' ? warning(false, 'Textarea elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled textarea ' + 'and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components') : void 0; |
|
didWarnValDefaultVal = true; |
|
} |
|
} |
|
|
|
var value = LinkedValueUtils.getValue(props); |
|
var initialValue = value; |
|
|
|
// Only bother fetching default value if we're going to use it |
|
if (value == null) { |
|
var defaultValue = props.defaultValue; |
|
// TODO (yungsters): Remove support for children content in <textarea>. |
|
var children = props.children; |
|
if (children != null) { |
|
if ("development" !== 'production') { |
|
"development" !== 'production' ? warning(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.') : void 0; |
|
} |
|
!(defaultValue == null) ? "development" !== 'production' ? invariant(false, 'If you supply `defaultValue` on a <textarea>, do not pass children.') : _prodInvariant('92') : void 0; |
|
if (Array.isArray(children)) { |
|
!(children.length <= 1) ? "development" !== 'production' ? invariant(false, '<textarea> can only have at most one child.') : _prodInvariant('93') : void 0; |
|
children = children[0]; |
|
} |
|
|
|
defaultValue = '' + children; |
|
} |
|
if (defaultValue == null) { |
|
defaultValue = ''; |
|
} |
|
initialValue = defaultValue; |
|
} |
|
|
|
inst._wrapperState = { |
|
initialValue: '' + initialValue, |
|
listeners: null, |
|
onChange: _handleChange.bind(inst) |
|
}; |
|
}, |
|
|
|
updateWrapper: function (inst) { |
|
var props = inst._currentElement.props; |
|
|
|
var node = ReactDOMComponentTree.getNodeFromInstance(inst); |
|
var value = LinkedValueUtils.getValue(props); |
|
if (value != null) { |
|
// Cast `value` to a string to ensure the value is set correctly. While |
|
// browsers typically do this as necessary, jsdom doesn't. |
|
var newValue = '' + value; |
|
|
|
// To avoid side effects (such as losing text selection), only set value if changed |
|
if (newValue !== node.value) { |
|
node.value = newValue; |
|
} |
|
if (props.defaultValue == null) { |
|
node.defaultValue = newValue; |
|
} |
|
} |
|
if (props.defaultValue != null) { |
|
node.defaultValue = props.defaultValue; |
|
} |
|
}, |
|
|
|
postMountWrapper: function (inst) { |
|
// This is in postMount because we need access to the DOM node, which is not |
|
// available until after the component has mounted. |
|
var node = ReactDOMComponentTree.getNodeFromInstance(inst); |
|
var textContent = node.textContent; |
|
|
|
// Only set node.value if textContent is equal to the expected |
|
// initial value. In IE10/IE11 there is a bug where the placeholder attribute |
|
// will populate textContent as well. |
|
// https://developer.microsoft.com/microsoft-edge/platform/issues/101525/ |
|
if (textContent === inst._wrapperState.initialValue) { |
|
node.value = textContent; |
|
} |
|
} |
|
}; |
|
|
|
function _handleChange(event) { |
|
var props = this._currentElement.props; |
|
var returnValue = LinkedValueUtils.executeOnChange(props, event); |
|
ReactUpdates.asap(forceUpdateIfMounted, this); |
|
return returnValue; |
|
} |
|
|
|
module.exports = ReactDOMTextarea; |
|
},{"125":125,"150":150,"157":157,"158":158,"24":24,"34":34,"82":82}],47:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2015-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125); |
|
|
|
var invariant = _dereq_(150); |
|
|
|
/** |
|
* Return the lowest common ancestor of A and B, or null if they are in |
|
* different trees. |
|
*/ |
|
function getLowestCommonAncestor(instA, instB) { |
|
!('_hostNode' in instA) ? "development" !== 'production' ? invariant(false, 'getNodeFromInstance: Invalid argument.') : _prodInvariant('33') : void 0; |
|
!('_hostNode' in instB) ? "development" !== 'production' ? invariant(false, 'getNodeFromInstance: Invalid argument.') : _prodInvariant('33') : void 0; |
|
|
|
var depthA = 0; |
|
for (var tempA = instA; tempA; tempA = tempA._hostParent) { |
|
depthA++; |
|
} |
|
var depthB = 0; |
|
for (var tempB = instB; tempB; tempB = tempB._hostParent) { |
|
depthB++; |
|
} |
|
|
|
// If A is deeper, crawl up. |
|
while (depthA - depthB > 0) { |
|
instA = instA._hostParent; |
|
depthA--; |
|
} |
|
|
|
// If B is deeper, crawl up. |
|
while (depthB - depthA > 0) { |
|
instB = instB._hostParent; |
|
depthB--; |
|
} |
|
|
|
// Walk in lockstep until we find a match. |
|
var depth = depthA; |
|
while (depth--) { |
|
if (instA === instB) { |
|
return instA; |
|
} |
|
instA = instA._hostParent; |
|
instB = instB._hostParent; |
|
} |
|
return null; |
|
} |
|
|
|
/** |
|
* Return if A is an ancestor of B. |
|
*/ |
|
function isAncestor(instA, instB) { |
|
!('_hostNode' in instA) ? "development" !== 'production' ? invariant(false, 'isAncestor: Invalid argument.') : _prodInvariant('35') : void 0; |
|
!('_hostNode' in instB) ? "development" !== 'production' ? invariant(false, 'isAncestor: Invalid argument.') : _prodInvariant('35') : void 0; |
|
|
|
while (instB) { |
|
if (instB === instA) { |
|
return true; |
|
} |
|
instB = instB._hostParent; |
|
} |
|
return false; |
|
} |
|
|
|
/** |
|
* Return the parent instance of the passed-in instance. |
|
*/ |
|
function getParentInstance(inst) { |
|
!('_hostNode' in inst) ? "development" !== 'production' ? invariant(false, 'getParentInstance: Invalid argument.') : _prodInvariant('36') : void 0; |
|
|
|
return inst._hostParent; |
|
} |
|
|
|
/** |
|
* Simulates the traversal of a two-phase, capture/bubble event dispatch. |
|
*/ |
|
function traverseTwoPhase(inst, fn, arg) { |
|
var path = []; |
|
while (inst) { |
|
path.push(inst); |
|
inst = inst._hostParent; |
|
} |
|
var i; |
|
for (i = path.length; i-- > 0;) { |
|
fn(path[i], 'captured', arg); |
|
} |
|
for (i = 0; i < path.length; i++) { |
|
fn(path[i], 'bubbled', arg); |
|
} |
|
} |
|
|
|
/** |
|
* Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that |
|
* should would receive a `mouseEnter` or `mouseLeave` event. |
|
* |
|
* Does not invoke the callback on the nearest common ancestor because nothing |
|
* "entered" or "left" that element. |
|
*/ |
|
function traverseEnterLeave(from, to, fn, argFrom, argTo) { |
|
var common = from && to ? getLowestCommonAncestor(from, to) : null; |
|
var pathFrom = []; |
|
while (from && from !== common) { |
|
pathFrom.push(from); |
|
from = from._hostParent; |
|
} |
|
var pathTo = []; |
|
while (to && to !== common) { |
|
pathTo.push(to); |
|
to = to._hostParent; |
|
} |
|
var i; |
|
for (i = 0; i < pathFrom.length; i++) { |
|
fn(pathFrom[i], 'bubbled', argFrom); |
|
} |
|
for (i = pathTo.length; i-- > 0;) { |
|
fn(pathTo[i], 'captured', argTo); |
|
} |
|
} |
|
|
|
module.exports = { |
|
isAncestor: isAncestor, |
|
getLowestCommonAncestor: getLowestCommonAncestor, |
|
getParentInstance: getParentInstance, |
|
traverseTwoPhase: traverseTwoPhase, |
|
traverseEnterLeave: traverseEnterLeave |
|
}; |
|
},{"125":125,"150":150}],48:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var React = _dereq_(134); |
|
var ReactDOM = _dereq_(31); |
|
|
|
var ReactDOMUMDEntry = ReactDOM; |
|
|
|
if ("development" !== 'production') { |
|
ReactDOMUMDEntry.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { |
|
// ReactPerf and ReactTestUtils currently only work with the DOM renderer |
|
// so we expose them from here, but only in DEV mode. |
|
ReactPerf: _dereq_(71), |
|
ReactTestUtils: _dereq_(80) |
|
}; |
|
} |
|
|
|
// Inject ReactDOM into React for the addons UMD build that depends on ReactDOM (TransitionGroup). |
|
// We can remove this after we deprecate and remove the addons UMD build. |
|
if (React.addons) { |
|
React.__SECRET_INJECTED_REACT_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = ReactDOMUMDEntry; |
|
} |
|
|
|
module.exports = ReactDOMUMDEntry; |
|
},{"134":134,"31":31,"71":71,"80":80}],49:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var DOMProperty = _dereq_(11); |
|
var EventPluginRegistry = _dereq_(18); |
|
var ReactComponentTreeHook = _dereq_(132); |
|
|
|
var warning = _dereq_(157); |
|
|
|
if ("development" !== 'production') { |
|
var reactProps = { |
|
children: true, |
|
dangerouslySetInnerHTML: true, |
|
key: true, |
|
ref: true, |
|
|
|
autoFocus: true, |
|
defaultValue: true, |
|
valueLink: true, |
|
defaultChecked: true, |
|
checkedLink: true, |
|
innerHTML: true, |
|
suppressContentEditableWarning: true, |
|
onFocusIn: true, |
|
onFocusOut: true |
|
}; |
|
var warnedProperties = {}; |
|
|
|
var validateProperty = function (tagName, name, debugID) { |
|
if (DOMProperty.properties.hasOwnProperty(name) || DOMProperty.isCustomAttribute(name)) { |
|
return true; |
|
} |
|
if (reactProps.hasOwnProperty(name) && reactProps[name] || warnedProperties.hasOwnProperty(name) && warnedProperties[name]) { |
|
return true; |
|
} |
|
if (EventPluginRegistry.registrationNameModules.hasOwnProperty(name)) { |
|
return true; |
|
} |
|
warnedProperties[name] = true; |
|
var lowerCasedName = name.toLowerCase(); |
|
|
|
// data-* attributes should be lowercase; suggest the lowercase version |
|
var standardName = DOMProperty.isCustomAttribute(lowerCasedName) ? lowerCasedName : DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? DOMProperty.getPossibleStandardName[lowerCasedName] : null; |
|
|
|
var registrationName = EventPluginRegistry.possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? EventPluginRegistry.possibleRegistrationNames[lowerCasedName] : null; |
|
|
|
if (standardName != null) { |
|
"development" !== 'production' ? warning(false, 'Unknown DOM property %s. Did you mean %s?%s', name, standardName, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0; |
|
return true; |
|
} else if (registrationName != null) { |
|
"development" !== 'production' ? warning(false, 'Unknown event handler property %s. Did you mean `%s`?%s', name, registrationName, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0; |
|
return true; |
|
} else { |
|
// We were unable to guess which prop the user intended. |
|
// It is likely that the user was just blindly spreading/forwarding props |
|
// Components should be careful to only render valid props/attributes. |
|
// Warning will be invoked in warnUnknownProperties to allow grouping. |
|
return false; |
|
} |
|
}; |
|
} |
|
|
|
var warnUnknownProperties = function (debugID, element) { |
|
var unknownProps = []; |
|
for (var key in element.props) { |
|
var isValid = validateProperty(element.type, key, debugID); |
|
if (!isValid) { |
|
unknownProps.push(key); |
|
} |
|
} |
|
|
|
var unknownPropString = unknownProps.map(function (prop) { |
|
return '`' + prop + '`'; |
|
}).join(', '); |
|
|
|
if (unknownProps.length === 1) { |
|
"development" !== 'production' ? warning(false, 'Unknown prop %s on <%s> tag. Remove this prop from the element. ' + 'For details, see https://fb.me/react-unknown-prop%s', unknownPropString, element.type, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0; |
|
} else if (unknownProps.length > 1) { |
|
"development" !== 'production' ? warning(false, 'Unknown props %s on <%s> tag. Remove these props from the element. ' + 'For details, see https://fb.me/react-unknown-prop%s', unknownPropString, element.type, ReactComponentTreeHook.getStackAddendumByID(debugID)) : void 0; |
|
} |
|
}; |
|
|
|
function handleElement(debugID, element) { |
|
if (element == null || typeof element.type !== 'string') { |
|
return; |
|
} |
|
if (element.type.indexOf('-') >= 0 || element.props.is) { |
|
return; |
|
} |
|
warnUnknownProperties(debugID, element); |
|
} |
|
|
|
var ReactDOMUnknownPropertyHook = { |
|
onBeforeMountComponent: function (debugID, element) { |
|
handleElement(debugID, element); |
|
}, |
|
onBeforeUpdateComponent: function (debugID, element) { |
|
handleElement(debugID, element); |
|
} |
|
}; |
|
|
|
module.exports = ReactDOMUnknownPropertyHook; |
|
},{"11":11,"132":132,"157":157,"18":18}],50:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2016-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var ReactInvalidSetStateWarningHook = _dereq_(65); |
|
var ReactHostOperationHistoryHook = _dereq_(60); |
|
var ReactComponentTreeHook = _dereq_(132); |
|
var ExecutionEnvironment = _dereq_(136); |
|
|
|
var performanceNow = _dereq_(155); |
|
var warning = _dereq_(157); |
|
|
|
var hooks = []; |
|
var didHookThrowForEvent = {}; |
|
|
|
function callHook(event, fn, context, arg1, arg2, arg3, arg4, arg5) { |
|
try { |
|
fn.call(context, arg1, arg2, arg3, arg4, arg5); |
|
} catch (e) { |
|
"development" !== 'production' ? warning(didHookThrowForEvent[event], 'Exception thrown by hook while handling %s: %s', event, e + '\n' + e.stack) : void 0; |
|
didHookThrowForEvent[event] = true; |
|
} |
|
} |
|
|
|
function emitEvent(event, arg1, arg2, arg3, arg4, arg5) { |
|
for (var i = 0; i < hooks.length; i++) { |
|
var hook = hooks[i]; |
|
var fn = hook[event]; |
|
if (fn) { |
|
callHook(event, fn, hook, arg1, arg2, arg3, arg4, arg5); |
|
} |
|
} |
|
} |
|
|
|
var isProfiling = false; |
|
var flushHistory = []; |
|
var lifeCycleTimerStack = []; |
|
var currentFlushNesting = 0; |
|
var currentFlushMeasurements = []; |
|
var currentFlushStartTime = 0; |
|
var currentTimerDebugID = null; |
|
var currentTimerStartTime = 0; |
|
var currentTimerNestedFlushDuration = 0; |
|
var currentTimerType = null; |
|
|
|
var lifeCycleTimerHasWarned = false; |
|
|
|
function clearHistory() { |
|
ReactComponentTreeHook.purgeUnmountedComponents(); |
|
ReactHostOperationHistoryHook.clearHistory(); |
|
} |
|
|
|
function getTreeSnapshot(registeredIDs) { |
|
return registeredIDs.reduce(function (tree, id) { |
|
var ownerID = ReactComponentTreeHook.getOwnerID(id); |
|
var parentID = ReactComponentTreeHook.getParentID(id); |
|
tree[id] = { |
|
displayName: ReactComponentTreeHook.getDisplayName(id), |
|
text: ReactComponentTreeHook.getText(id), |
|
updateCount: ReactComponentTreeHook.getUpdateCount(id), |
|
childIDs: ReactComponentTreeHook.getChildIDs(id), |
|
// Text nodes don't have owners but this is close enough. |
|
ownerID: ownerID || parentID && ReactComponentTreeHook.getOwnerID(parentID) || 0, |
|
parentID: parentID |
|
}; |
|
return tree; |
|
}, {}); |
|
} |
|
|
|
function resetMeasurements() { |
|
var previousStartTime = currentFlushStartTime; |
|
var previousMeasurements = currentFlushMeasurements; |
|
var previousOperations = ReactHostOperationHistoryHook.getHistory(); |
|
|
|
if (currentFlushNesting === 0) { |
|
currentFlushStartTime = 0; |
|
currentFlushMeasurements = []; |
|
clearHistory(); |
|
return; |
|
} |
|
|
|
if (previousMeasurements.length || previousOperations.length) { |
|
var registeredIDs = ReactComponentTreeHook.getRegisteredIDs(); |
|
flushHistory.push({ |
|
duration: performanceNow() - previousStartTime, |
|
measurements: previousMeasurements || [], |
|
operations: previousOperations || [], |
|
treeSnapshot: getTreeSnapshot(registeredIDs) |
|
}); |
|
} |
|
|
|
clearHistory(); |
|
currentFlushStartTime = performanceNow(); |
|
currentFlushMeasurements = []; |
|
} |
|
|
|
function checkDebugID(debugID) { |
|
var allowRoot = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; |
|
|
|
if (allowRoot && debugID === 0) { |
|
return; |
|
} |
|
if (!debugID) { |
|
"development" !== 'production' ? warning(false, 'ReactDebugTool: debugID may not be empty.') : void 0; |
|
} |
|
} |
|
|
|
function beginLifeCycleTimer(debugID, timerType) { |
|
if (currentFlushNesting === 0) { |
|
return; |
|
} |
|
if (currentTimerType && !lifeCycleTimerHasWarned) { |
|
"development" !== 'production' ? warning(false, 'There is an internal error in the React performance measurement code. ' + 'Did not expect %s timer to start while %s timer is still in ' + 'progress for %s instance.', timerType, currentTimerType || 'no', debugID === currentTimerDebugID ? 'the same' : 'another') : void 0; |
|
lifeCycleTimerHasWarned = true; |
|
} |
|
currentTimerStartTime = performanceNow(); |
|
currentTimerNestedFlushDuration = 0; |
|
currentTimerDebugID = debugID; |
|
currentTimerType = timerType; |
|
} |
|
|
|
function endLifeCycleTimer(debugID, timerType) { |
|
if (currentFlushNesting === 0) { |
|
return; |
|
} |
|
if (currentTimerType !== timerType && !lifeCycleTimerHasWarned) { |
|
"development" !== 'production' ? warning(false, 'There is an internal error in the React performance measurement code. ' + 'We did not expect %s timer to stop while %s timer is still in ' + 'progress for %s instance. Please report this as a bug in React.', timerType, currentTimerType || 'no', debugID === currentTimerDebugID ? 'the same' : 'another') : void 0; |
|
lifeCycleTimerHasWarned = true; |
|
} |
|
if (isProfiling) { |
|
currentFlushMeasurements.push({ |
|
timerType: timerType, |
|
instanceID: debugID, |
|
duration: performanceNow() - currentTimerStartTime - currentTimerNestedFlushDuration |
|
}); |
|
} |
|
currentTimerStartTime = 0; |
|
currentTimerNestedFlushDuration = 0; |
|
currentTimerDebugID = null; |
|
currentTimerType = null; |
|
} |
|
|
|
function pauseCurrentLifeCycleTimer() { |
|
var currentTimer = { |
|
startTime: currentTimerStartTime, |
|
nestedFlushStartTime: performanceNow(), |
|
debugID: currentTimerDebugID, |
|
timerType: currentTimerType |
|
}; |
|
lifeCycleTimerStack.push(currentTimer); |
|
currentTimerStartTime = 0; |
|
currentTimerNestedFlushDuration = 0; |
|
currentTimerDebugID = null; |
|
currentTimerType = null; |
|
} |
|
|
|
function resumeCurrentLifeCycleTimer() { |
|
var _lifeCycleTimerStack$ = lifeCycleTimerStack.pop(), |
|
startTime = _lifeCycleTimerStack$.startTime, |
|
nestedFlushStartTime = _lifeCycleTimerStack$.nestedFlushStartTime, |
|
debugID = _lifeCycleTimerStack$.debugID, |
|
timerType = _lifeCycleTimerStack$.timerType; |
|
|
|
var nestedFlushDuration = performanceNow() - nestedFlushStartTime; |
|
currentTimerStartTime = startTime; |
|
currentTimerNestedFlushDuration += nestedFlushDuration; |
|
currentTimerDebugID = debugID; |
|
currentTimerType = timerType; |
|
} |
|
|
|
var lastMarkTimeStamp = 0; |
|
var canUsePerformanceMeasure = |
|
// $FlowFixMe https://github.com/facebook/flow/issues/2345 |
|
typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function'; |
|
|
|
function shouldMark(debugID) { |
|
if (!isProfiling || !canUsePerformanceMeasure) { |
|
return false; |
|
} |
|
var element = ReactComponentTreeHook.getElement(debugID); |
|
if (element == null || typeof element !== 'object') { |
|
return false; |
|
} |
|
var isHostElement = typeof element.type === 'string'; |
|
if (isHostElement) { |
|
return false; |
|
} |
|
return true; |
|
} |
|
|
|
function markBegin(debugID, markType) { |
|
if (!shouldMark(debugID)) { |
|
return; |
|
} |
|
|
|
var markName = debugID + '::' + markType; |
|
lastMarkTimeStamp = performanceNow(); |
|
performance.mark(markName); |
|
} |
|
|
|
function markEnd(debugID, markType) { |
|
if (!shouldMark(debugID)) { |
|
return; |
|
} |
|
|
|
var markName = debugID + '::' + markType; |
|
var displayName = ReactComponentTreeHook.getDisplayName(debugID) || 'Unknown'; |
|
|
|
// Chrome has an issue of dropping markers recorded too fast: |
|
// https://bugs.chromium.org/p/chromium/issues/detail?id=640652 |
|
// To work around this, we will not report very small measurements. |
|
// I determined the magic number by tweaking it back and forth. |
|
// 0.05ms was enough to prevent the issue, but I set it to 0.1ms to be safe. |
|
// When the bug is fixed, we can `measure()` unconditionally if we want to. |
|
var timeStamp = performanceNow(); |
|
if (timeStamp - lastMarkTimeStamp > 0.1) { |
|
var measurementName = displayName + ' [' + markType + ']'; |
|
performance.measure(measurementName, markName); |
|
} |
|
|
|
performance.clearMarks(markName); |
|
performance.clearMeasures(measurementName); |
|
} |
|
|
|
var ReactDebugTool = { |
|
addHook: function (hook) { |
|
hooks.push(hook); |
|
}, |
|
removeHook: function (hook) { |
|
for (var i = 0; i < hooks.length; i++) { |
|
if (hooks[i] === hook) { |
|
hooks.splice(i, 1); |
|
i--; |
|
} |
|
} |
|
}, |
|
isProfiling: function () { |
|
return isProfiling; |
|
}, |
|
beginProfiling: function () { |
|
if (isProfiling) { |
|
return; |
|
} |
|
|
|
isProfiling = true; |
|
flushHistory.length = 0; |
|
resetMeasurements(); |
|
ReactDebugTool.addHook(ReactHostOperationHistoryHook); |
|
}, |
|
endProfiling: function () { |
|
if (!isProfiling) { |
|
return; |
|
} |
|
|
|
isProfiling = false; |
|
resetMeasurements(); |
|
ReactDebugTool.removeHook(ReactHostOperationHistoryHook); |
|
}, |
|
getFlushHistory: function () { |
|
return flushHistory; |
|
}, |
|
onBeginFlush: function () { |
|
currentFlushNesting++; |
|
resetMeasurements(); |
|
pauseCurrentLifeCycleTimer(); |
|
emitEvent('onBeginFlush'); |
|
}, |
|
onEndFlush: function () { |
|
resetMeasurements(); |
|
currentFlushNesting--; |
|
resumeCurrentLifeCycleTimer(); |
|
emitEvent('onEndFlush'); |
|
}, |
|
onBeginLifeCycleTimer: function (debugID, timerType) { |
|
checkDebugID(debugID); |
|
emitEvent('onBeginLifeCycleTimer', debugID, timerType); |
|
markBegin(debugID, timerType); |
|
beginLifeCycleTimer(debugID, timerType); |
|
}, |
|
onEndLifeCycleTimer: function (debugID, timerType) { |
|
checkDebugID(debugID); |
|
endLifeCycleTimer(debugID, timerType); |
|
markEnd(debugID, timerType); |
|
emitEvent('onEndLifeCycleTimer', debugID, timerType); |
|
}, |
|
onBeginProcessingChildContext: function () { |
|
emitEvent('onBeginProcessingChildContext'); |
|
}, |
|
onEndProcessingChildContext: function () { |
|
emitEvent('onEndProcessingChildContext'); |
|
}, |
|
onHostOperation: function (operation) { |
|
checkDebugID(operation.instanceID); |
|
emitEvent('onHostOperation', operation); |
|
}, |
|
onSetState: function () { |
|
emitEvent('onSetState'); |
|
}, |
|
onSetChildren: function (debugID, childDebugIDs) { |
|
checkDebugID(debugID); |
|
childDebugIDs.forEach(checkDebugID); |
|
emitEvent('onSetChildren', debugID, childDebugIDs); |
|
}, |
|
onBeforeMountComponent: function (debugID, element, parentDebugID) { |
|
checkDebugID(debugID); |
|
checkDebugID(parentDebugID, true); |
|
emitEvent('onBeforeMountComponent', debugID, element, parentDebugID); |
|
markBegin(debugID, 'mount'); |
|
}, |
|
onMountComponent: function (debugID) { |
|
checkDebugID(debugID); |
|
markEnd(debugID, 'mount'); |
|
emitEvent('onMountComponent', debugID); |
|
}, |
|
onBeforeUpdateComponent: function (debugID, element) { |
|
checkDebugID(debugID); |
|
emitEvent('onBeforeUpdateComponent', debugID, element); |
|
markBegin(debugID, 'update'); |
|
}, |
|
onUpdateComponent: function (debugID) { |
|
checkDebugID(debugID); |
|
markEnd(debugID, 'update'); |
|
emitEvent('onUpdateComponent', debugID); |
|
}, |
|
onBeforeUnmountComponent: function (debugID) { |
|
checkDebugID(debugID); |
|
emitEvent('onBeforeUnmountComponent', debugID); |
|
markBegin(debugID, 'unmount'); |
|
}, |
|
onUnmountComponent: function (debugID) { |
|
checkDebugID(debugID); |
|
markEnd(debugID, 'unmount'); |
|
emitEvent('onUnmountComponent', debugID); |
|
}, |
|
onTestEvent: function () { |
|
emitEvent('onTestEvent'); |
|
} |
|
}; |
|
|
|
// TODO remove these when RN/www gets updated |
|
ReactDebugTool.addDevtool = ReactDebugTool.addHook; |
|
ReactDebugTool.removeDevtool = ReactDebugTool.removeHook; |
|
|
|
ReactDebugTool.addHook(ReactInvalidSetStateWarningHook); |
|
ReactDebugTool.addHook(ReactComponentTreeHook); |
|
var url = ExecutionEnvironment.canUseDOM && window.location.href || ''; |
|
if (/[?&]react_perf\b/.test(url)) { |
|
ReactDebugTool.beginProfiling(); |
|
} |
|
|
|
module.exports = ReactDebugTool; |
|
},{"132":132,"136":136,"155":155,"157":157,"60":60,"65":65}],51:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _assign = _dereq_(158); |
|
|
|
var ReactUpdates = _dereq_(82); |
|
var Transaction = _dereq_(100); |
|
|
|
var emptyFunction = _dereq_(142); |
|
|
|
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(); |
|
} |
|
|
|
_assign(ReactDefaultBatchingStrategyTransaction.prototype, Transaction, { |
|
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, a, b, c, d, e) { |
|
var alreadyBatchingUpdates = ReactDefaultBatchingStrategy.isBatchingUpdates; |
|
|
|
ReactDefaultBatchingStrategy.isBatchingUpdates = true; |
|
|
|
// The code is written this way to avoid extra allocations |
|
if (alreadyBatchingUpdates) { |
|
return callback(a, b, c, d, e); |
|
} else { |
|
return transaction.perform(callback, null, a, b, c, d, e); |
|
} |
|
} |
|
}; |
|
|
|
module.exports = ReactDefaultBatchingStrategy; |
|
},{"100":100,"142":142,"158":158,"82":82}],52:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var ARIADOMPropertyConfig = _dereq_(1); |
|
var BeforeInputEventPlugin = _dereq_(3); |
|
var ChangeEventPlugin = _dereq_(7); |
|
var DefaultEventPluginOrder = _dereq_(14); |
|
var EnterLeaveEventPlugin = _dereq_(15); |
|
var HTMLDOMPropertyConfig = _dereq_(22); |
|
var ReactComponentBrowserEnvironment = _dereq_(28); |
|
var ReactDOMComponent = _dereq_(32); |
|
var ReactDOMComponentTree = _dereq_(34); |
|
var ReactDOMEmptyComponent = _dereq_(36); |
|
var ReactDOMTreeTraversal = _dereq_(47); |
|
var ReactDOMTextComponent = _dereq_(45); |
|
var ReactDefaultBatchingStrategy = _dereq_(51); |
|
var ReactEventListener = _dereq_(57); |
|
var ReactInjection = _dereq_(61); |
|
var ReactReconcileTransaction = _dereq_(74); |
|
var SVGDOMPropertyConfig = _dereq_(84); |
|
var SelectEventPlugin = _dereq_(85); |
|
var SimpleEventPlugin = _dereq_(86); |
|
|
|
var alreadyInjected = false; |
|
|
|
function inject() { |
|
if (alreadyInjected) { |
|
// TODO: This is currently true because these injections are shared between |
|
// the client and the server package. They should be built independently |
|
// and not share any injection state. Then this problem will be solved. |
|
return; |
|
} |
|
alreadyInjected = true; |
|
|
|
ReactInjection.EventEmitter.injectReactEventListener(ReactEventListener); |
|
|
|
/** |
|
* Inject modules for resolving DOM hierarchy and plugin ordering. |
|
*/ |
|
ReactInjection.EventPluginHub.injectEventPluginOrder(DefaultEventPluginOrder); |
|
ReactInjection.EventPluginUtils.injectComponentTree(ReactDOMComponentTree); |
|
ReactInjection.EventPluginUtils.injectTreeTraversal(ReactDOMTreeTraversal); |
|
|
|
/** |
|
* Some important event plugins included by default (without having to require |
|
* them). |
|
*/ |
|
ReactInjection.EventPluginHub.injectEventPluginsByName({ |
|
SimpleEventPlugin: SimpleEventPlugin, |
|
EnterLeaveEventPlugin: EnterLeaveEventPlugin, |
|
ChangeEventPlugin: ChangeEventPlugin, |
|
SelectEventPlugin: SelectEventPlugin, |
|
BeforeInputEventPlugin: BeforeInputEventPlugin |
|
}); |
|
|
|
ReactInjection.HostComponent.injectGenericComponentClass(ReactDOMComponent); |
|
|
|
ReactInjection.HostComponent.injectTextComponentClass(ReactDOMTextComponent); |
|
|
|
ReactInjection.DOMProperty.injectDOMPropertyConfig(ARIADOMPropertyConfig); |
|
ReactInjection.DOMProperty.injectDOMPropertyConfig(HTMLDOMPropertyConfig); |
|
ReactInjection.DOMProperty.injectDOMPropertyConfig(SVGDOMPropertyConfig); |
|
|
|
ReactInjection.EmptyComponent.injectEmptyComponentFactory(function (instantiate) { |
|
return new ReactDOMEmptyComponent(instantiate); |
|
}); |
|
|
|
ReactInjection.Updates.injectReconcileTransaction(ReactReconcileTransaction); |
|
ReactInjection.Updates.injectBatchingStrategy(ReactDefaultBatchingStrategy); |
|
|
|
ReactInjection.Component.injectEnvironment(ReactComponentBrowserEnvironment); |
|
} |
|
|
|
module.exports = { |
|
inject: inject |
|
}; |
|
},{"1":1,"14":14,"15":15,"22":22,"28":28,"3":3,"32":32,"34":34,"36":36,"45":45,"47":47,"51":51,"57":57,"61":61,"7":7,"74":74,"84":84,"85":85,"86":86}],53:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2014-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
// The Symbol used to tag the ReactElement type. If there is no native Symbol |
|
// nor polyfill, then a plain number is used for performance. |
|
|
|
var REACT_ELEMENT_TYPE = typeof Symbol === 'function' && Symbol['for'] && Symbol['for']('react.element') || 0xeac7; |
|
|
|
module.exports = REACT_ELEMENT_TYPE; |
|
},{}],54:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2014-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var emptyComponentFactory; |
|
|
|
var ReactEmptyComponentInjection = { |
|
injectEmptyComponentFactory: function (factory) { |
|
emptyComponentFactory = factory; |
|
} |
|
}; |
|
|
|
var ReactEmptyComponent = { |
|
create: function (instantiate) { |
|
return emptyComponentFactory(instantiate); |
|
} |
|
}; |
|
|
|
ReactEmptyComponent.injection = ReactEmptyComponentInjection; |
|
|
|
module.exports = ReactEmptyComponent; |
|
},{}],55:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var caughtError = null; |
|
|
|
/** |
|
* Call a function while guarding against errors that happens within it. |
|
* |
|
* @param {String} name of the guard to use for logging or debugging |
|
* @param {Function} func The function to invoke |
|
* @param {*} a First argument |
|
* @param {*} b Second argument |
|
*/ |
|
function invokeGuardedCallback(name, func, a) { |
|
try { |
|
func(a); |
|
} catch (x) { |
|
if (caughtError === null) { |
|
caughtError = x; |
|
} |
|
} |
|
} |
|
|
|
var ReactErrorUtils = { |
|
invokeGuardedCallback: invokeGuardedCallback, |
|
|
|
/** |
|
* Invoked by ReactTestUtils.Simulate so that any errors thrown by the event |
|
* handler are sure to be rethrown by rethrowCaughtError. |
|
*/ |
|
invokeGuardedCallbackWithCatch: invokeGuardedCallback, |
|
|
|
/** |
|
* During execution of guarded functions we will capture the first error which |
|
* we will rethrow to be handled by the top level error handler. |
|
*/ |
|
rethrowCaughtError: function () { |
|
if (caughtError) { |
|
var error = caughtError; |
|
caughtError = null; |
|
throw error; |
|
} |
|
} |
|
}; |
|
|
|
if ("development" !== 'production') { |
|
/** |
|
* To help development we can get better devtools integration by simulating a |
|
* real browser event. |
|
*/ |
|
if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') { |
|
var fakeNode = document.createElement('react'); |
|
ReactErrorUtils.invokeGuardedCallback = function (name, func, a) { |
|
var boundFunc = func.bind(null, a); |
|
var evtType = 'react-' + name; |
|
fakeNode.addEventListener(evtType, boundFunc, false); |
|
var evt = document.createEvent('Event'); |
|
// $FlowFixMe https://github.com/facebook/flow/issues/2336 |
|
evt.initEvent(evtType, false, false); |
|
fakeNode.dispatchEvent(evt); |
|
fakeNode.removeEventListener(evtType, boundFunc, false); |
|
}; |
|
} |
|
} |
|
|
|
module.exports = ReactErrorUtils; |
|
},{}],56:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var EventPluginHub = _dereq_(17); |
|
|
|
function runEventQueueInBatch(events) { |
|
EventPluginHub.enqueueEvents(events); |
|
EventPluginHub.processEventQueue(false); |
|
} |
|
|
|
var ReactEventEmitterMixin = { |
|
|
|
/** |
|
* Streams a fired top-level event to `EventPluginHub` where plugins have the |
|
* opportunity to create `ReactEvent`s to be dispatched. |
|
*/ |
|
handleTopLevel: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { |
|
var events = EventPluginHub.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget); |
|
runEventQueueInBatch(events); |
|
} |
|
}; |
|
|
|
module.exports = ReactEventEmitterMixin; |
|
},{"17":17}],57:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _assign = _dereq_(158); |
|
|
|
var EventListener = _dereq_(135); |
|
var ExecutionEnvironment = _dereq_(136); |
|
var PooledClass = _dereq_(25); |
|
var ReactDOMComponentTree = _dereq_(34); |
|
var ReactUpdates = _dereq_(82); |
|
|
|
var getEventTarget = _dereq_(114); |
|
var getUnboundedScrollPosition = _dereq_(147); |
|
|
|
/** |
|
* Find the deepest React component completely containing the root of the |
|
* passed-in instance (for use when entire React trees are nested within each |
|
* other). If React trees are not nested, returns null. |
|
*/ |
|
function findParent(inst) { |
|
// 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. |
|
while (inst._hostParent) { |
|
inst = inst._hostParent; |
|
} |
|
var rootNode = ReactDOMComponentTree.getNodeFromInstance(inst); |
|
var container = rootNode.parentNode; |
|
return ReactDOMComponentTree.getClosestInstanceFromNode(container); |
|
} |
|
|
|
// Used to store ancestor hierarchy in top level callback |
|
function TopLevelCallbackBookKeeping(topLevelType, nativeEvent) { |
|
this.topLevelType = topLevelType; |
|
this.nativeEvent = nativeEvent; |
|
this.ancestors = []; |
|
} |
|
_assign(TopLevelCallbackBookKeeping.prototype, { |
|
destructor: function () { |
|
this.topLevelType = null; |
|
this.nativeEvent = null; |
|
this.ancestors.length = 0; |
|
} |
|
}); |
|
PooledClass.addPoolingTo(TopLevelCallbackBookKeeping, PooledClass.twoArgumentPooler); |
|
|
|
function handleTopLevelImpl(bookKeeping) { |
|
var nativeEventTarget = getEventTarget(bookKeeping.nativeEvent); |
|
var targetInst = ReactDOMComponentTree.getClosestInstanceFromNode(nativeEventTarget); |
|
|
|
// 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 = targetInst; |
|
do { |
|
bookKeeping.ancestors.push(ancestor); |
|
ancestor = ancestor && findParent(ancestor); |
|
} while (ancestor); |
|
|
|
for (var i = 0; i < bookKeeping.ancestors.length; i++) { |
|
targetInst = bookKeeping.ancestors[i]; |
|
ReactEventListener._handleTopLevel(bookKeeping.topLevelType, targetInst, bookKeeping.nativeEvent, getEventTarget(bookKeeping.nativeEvent)); |
|
} |
|
} |
|
|
|
function scrollValueMonitor(cb) { |
|
var scrollPosition = getUnboundedScrollPosition(window); |
|
cb(scrollPosition); |
|
} |
|
|
|
var ReactEventListener = { |
|
_enabled: true, |
|
_handleTopLevel: null, |
|
|
|
WINDOW_HANDLE: ExecutionEnvironment.canUseDOM ? window : null, |
|
|
|
setHandleTopLevel: function (handleTopLevel) { |
|
ReactEventListener._handleTopLevel = handleTopLevel; |
|
}, |
|
|
|
setEnabled: function (enabled) { |
|
ReactEventListener._enabled = !!enabled; |
|
}, |
|
|
|
isEnabled: function () { |
|
return ReactEventListener._enabled; |
|
}, |
|
|
|
/** |
|
* Traps top-level events by using event bubbling. |
|
* |
|
* @param {string} topLevelType Record from `EventConstants`. |
|
* @param {string} handlerBaseName Event name (e.g. "click"). |
|
* @param {object} element Element on which to attach listener. |
|
* @return {?object} An object with a remove function which will forcefully |
|
* remove the listener. |
|
* @internal |
|
*/ |
|
trapBubbledEvent: function (topLevelType, handlerBaseName, element) { |
|
if (!element) { |
|
return null; |
|
} |
|
return EventListener.listen(element, handlerBaseName, ReactEventListener.dispatchEvent.bind(null, 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 {object} element Element on which to attach listener. |
|
* @return {?object} An object with a remove function which will forcefully |
|
* remove the listener. |
|
* @internal |
|
*/ |
|
trapCapturedEvent: function (topLevelType, handlerBaseName, element) { |
|
if (!element) { |
|
return null; |
|
} |
|
return EventListener.capture(element, handlerBaseName, ReactEventListener.dispatchEvent.bind(null, topLevelType)); |
|
}, |
|
|
|
monitorScrollValue: function (refresh) { |
|
var callback = scrollValueMonitor.bind(null, refresh); |
|
EventListener.listen(window, 'scroll', callback); |
|
}, |
|
|
|
dispatchEvent: function (topLevelType, nativeEvent) { |
|
if (!ReactEventListener._enabled) { |
|
return; |
|
} |
|
|
|
var bookKeeping = TopLevelCallbackBookKeeping.getPooled(topLevelType, nativeEvent); |
|
try { |
|
// Event queue being processed in the same cycle allows |
|
// `preventDefault`. |
|
ReactUpdates.batchedUpdates(handleTopLevelImpl, bookKeeping); |
|
} finally { |
|
TopLevelCallbackBookKeeping.release(bookKeeping); |
|
} |
|
} |
|
}; |
|
|
|
module.exports = ReactEventListener; |
|
},{"114":114,"135":135,"136":136,"147":147,"158":158,"25":25,"34":34,"82":82}],58:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var ReactFeatureFlags = { |
|
// When true, call console.time() before and .timeEnd() after each top-level |
|
// render (both initial renders and updates). Useful when looking at prod-mode |
|
// timeline profiles in Chrome, for example. |
|
logTopLevelRenders: false |
|
}; |
|
|
|
module.exports = ReactFeatureFlags; |
|
},{}],59:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2014-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125); |
|
|
|
var invariant = _dereq_(150); |
|
|
|
var genericComponentClass = null; |
|
var textComponentClass = null; |
|
|
|
var ReactHostComponentInjection = { |
|
// This accepts a class that receives the tag string. This is a catch all |
|
// that can render any kind of tag. |
|
injectGenericComponentClass: function (componentClass) { |
|
genericComponentClass = componentClass; |
|
}, |
|
// This accepts a text component class that takes the text string to be |
|
// rendered as props. |
|
injectTextComponentClass: function (componentClass) { |
|
textComponentClass = componentClass; |
|
} |
|
}; |
|
|
|
/** |
|
* Get a host internal component class for a specific tag. |
|
* |
|
* @param {ReactElement} element The element to create. |
|
* @return {function} The internal class constructor function. |
|
*/ |
|
function createInternalComponent(element) { |
|
!genericComponentClass ? "development" !== 'production' ? invariant(false, 'There is no registered component for the tag %s', element.type) : _prodInvariant('111', element.type) : void 0; |
|
return new genericComponentClass(element); |
|
} |
|
|
|
/** |
|
* @param {ReactText} text |
|
* @return {ReactComponent} |
|
*/ |
|
function createInstanceForText(text) { |
|
return new textComponentClass(text); |
|
} |
|
|
|
/** |
|
* @param {ReactComponent} component |
|
* @return {boolean} |
|
*/ |
|
function isTextComponent(component) { |
|
return component instanceof textComponentClass; |
|
} |
|
|
|
var ReactHostComponent = { |
|
createInternalComponent: createInternalComponent, |
|
createInstanceForText: createInstanceForText, |
|
isTextComponent: isTextComponent, |
|
injection: ReactHostComponentInjection |
|
}; |
|
|
|
module.exports = ReactHostComponent; |
|
},{"125":125,"150":150}],60:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2016-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var history = []; |
|
|
|
var ReactHostOperationHistoryHook = { |
|
onHostOperation: function (operation) { |
|
history.push(operation); |
|
}, |
|
clearHistory: function () { |
|
if (ReactHostOperationHistoryHook._preventClearing) { |
|
// Should only be used for tests. |
|
return; |
|
} |
|
|
|
history = []; |
|
}, |
|
getHistory: function () { |
|
return history; |
|
} |
|
}; |
|
|
|
module.exports = ReactHostOperationHistoryHook; |
|
},{}],61:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var DOMProperty = _dereq_(11); |
|
var EventPluginHub = _dereq_(17); |
|
var EventPluginUtils = _dereq_(19); |
|
var ReactComponentEnvironment = _dereq_(29); |
|
var ReactEmptyComponent = _dereq_(54); |
|
var ReactBrowserEventEmitter = _dereq_(26); |
|
var ReactHostComponent = _dereq_(59); |
|
var ReactUpdates = _dereq_(82); |
|
|
|
var ReactInjection = { |
|
Component: ReactComponentEnvironment.injection, |
|
DOMProperty: DOMProperty.injection, |
|
EmptyComponent: ReactEmptyComponent.injection, |
|
EventPluginHub: EventPluginHub.injection, |
|
EventPluginUtils: EventPluginUtils.injection, |
|
EventEmitter: ReactBrowserEventEmitter.injection, |
|
HostComponent: ReactHostComponent.injection, |
|
Updates: ReactUpdates.injection |
|
}; |
|
|
|
module.exports = ReactInjection; |
|
},{"11":11,"17":17,"19":19,"26":26,"29":29,"54":54,"59":59,"82":82}],62:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var ReactDOMSelection = _dereq_(44); |
|
|
|
var containsNode = _dereq_(139); |
|
var focusNode = _dereq_(144); |
|
var getActiveElement = _dereq_(145); |
|
|
|
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) { |
|
var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase(); |
|
return nodeName && (nodeName === 'input' && elem.type === 'text' || 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.nodeName.toLowerCase() === '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 (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.nodeName.toLowerCase() === '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; |
|
},{"139":139,"144":144,"145":145,"44":44}],63:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
/** |
|
* `ReactInstanceMap` maintains a mapping from a public facing stateful |
|
* instance (key) and the internal representation (value). This allows public |
|
* methods to accept the user facing instance as an argument and map them back |
|
* to internal methods. |
|
*/ |
|
|
|
// TODO: Replace this with ES6: var ReactInstanceMap = new Map(); |
|
|
|
var ReactInstanceMap = { |
|
|
|
/** |
|
* This API should be called `delete` but we'd have to make sure to always |
|
* transform these to strings for IE support. When this transform is fully |
|
* supported we can rename it. |
|
*/ |
|
remove: function (key) { |
|
key._reactInternalInstance = undefined; |
|
}, |
|
|
|
get: function (key) { |
|
return key._reactInternalInstance; |
|
}, |
|
|
|
has: function (key) { |
|
return key._reactInternalInstance !== undefined; |
|
}, |
|
|
|
set: function (key, value) { |
|
key._reactInternalInstance = value; |
|
} |
|
|
|
}; |
|
|
|
module.exports = ReactInstanceMap; |
|
},{}],64:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2016-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
// Trust the developer to only use ReactInstrumentation with a __DEV__ check |
|
|
|
var debugTool = null; |
|
|
|
if ("development" !== 'production') { |
|
var ReactDebugTool = _dereq_(50); |
|
debugTool = ReactDebugTool; |
|
} |
|
|
|
module.exports = { debugTool: debugTool }; |
|
},{"50":50}],65:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2016-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var warning = _dereq_(157); |
|
|
|
if ("development" !== 'production') { |
|
var processingChildContext = false; |
|
|
|
var warnInvalidSetState = function () { |
|
"development" !== 'production' ? warning(!processingChildContext, 'setState(...): Cannot call setState() inside getChildContext()') : void 0; |
|
}; |
|
} |
|
|
|
var ReactInvalidSetStateWarningHook = { |
|
onBeginProcessingChildContext: function () { |
|
processingChildContext = true; |
|
}, |
|
onEndProcessingChildContext: function () { |
|
processingChildContext = false; |
|
}, |
|
onSetState: function () { |
|
warnInvalidSetState(); |
|
} |
|
}; |
|
|
|
module.exports = ReactInvalidSetStateWarningHook; |
|
},{"157":157}],66:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var adler32 = _dereq_(103); |
|
|
|
var TAG_END = /\/?>/; |
|
var COMMENT_START = /^<\!\-\-/; |
|
|
|
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); |
|
|
|
// Add checksum (handle both parent tags, comments and self-closing tags) |
|
if (COMMENT_START.test(markup)) { |
|
return markup; |
|
} else { |
|
return markup.replace(TAG_END, ' ' + 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; |
|
},{"103":103}],67:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125); |
|
|
|
var DOMLazyTree = _dereq_(9); |
|
var DOMProperty = _dereq_(11); |
|
var React = _dereq_(134); |
|
var ReactBrowserEventEmitter = _dereq_(26); |
|
var ReactCurrentOwner = _dereq_(133); |
|
var ReactDOMComponentTree = _dereq_(34); |
|
var ReactDOMContainerInfo = _dereq_(35); |
|
var ReactDOMFeatureFlags = _dereq_(37); |
|
var ReactFeatureFlags = _dereq_(58); |
|
var ReactInstanceMap = _dereq_(63); |
|
var ReactInstrumentation = _dereq_(64); |
|
var ReactMarkupChecksum = _dereq_(66); |
|
var ReactReconciler = _dereq_(75); |
|
var ReactUpdateQueue = _dereq_(81); |
|
var ReactUpdates = _dereq_(82); |
|
|
|
var emptyObject = _dereq_(143); |
|
var instantiateReactComponent = _dereq_(121); |
|
var invariant = _dereq_(150); |
|
var setInnerHTML = _dereq_(127); |
|
var shouldUpdateReactComponent = _dereq_(129); |
|
var warning = _dereq_(157); |
|
|
|
var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME; |
|
var ROOT_ATTR_NAME = DOMProperty.ROOT_ATTRIBUTE_NAME; |
|
|
|
var ELEMENT_NODE_TYPE = 1; |
|
var DOC_NODE_TYPE = 9; |
|
var DOCUMENT_FRAGMENT_NODE_TYPE = 11; |
|
|
|
var instancesByReactRootID = {}; |
|
|
|
/** |
|
* Finds the index of the first character |
|
* that's not common between the two given strings. |
|
* |
|
* @return {number} the index of the character where the strings diverge |
|
*/ |
|
function firstDifferenceIndex(string1, string2) { |
|
var minLen = Math.min(string1.length, string2.length); |
|
for (var i = 0; i < minLen; i++) { |
|
if (string1.charAt(i) !== string2.charAt(i)) { |
|
return i; |
|
} |
|
} |
|
return string1.length === string2.length ? -1 : minLen; |
|
} |
|
|
|
/** |
|
* @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; |
|
} |
|
} |
|
|
|
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.getAttribute && node.getAttribute(ATTR_NAME) || ''; |
|
} |
|
|
|
/** |
|
* Mounts this component and inserts it into the DOM. |
|
* |
|
* @param {ReactComponent} componentInstance The instance to mount. |
|
* @param {DOMElement} container DOM element to mount into. |
|
* @param {ReactReconcileTransaction} transaction |
|
* @param {boolean} shouldReuseMarkup If true, do not insert markup |
|
*/ |
|
function mountComponentIntoNode(wrapperInstance, container, transaction, shouldReuseMarkup, context) { |
|
var markerName; |
|
if (ReactFeatureFlags.logTopLevelRenders) { |
|
var wrappedElement = wrapperInstance._currentElement.props.child; |
|
var type = wrappedElement.type; |
|
markerName = 'React mount: ' + (typeof type === 'string' ? type : type.displayName || type.name); |
|
console.time(markerName); |
|
} |
|
|
|
var markup = ReactReconciler.mountComponent(wrapperInstance, transaction, null, ReactDOMContainerInfo(wrapperInstance, container), context, 0 /* parentDebugID */ |
|
); |
|
|
|
if (markerName) { |
|
console.timeEnd(markerName); |
|
} |
|
|
|
wrapperInstance._renderedComponent._topLevelWrapper = wrapperInstance; |
|
ReactMount._mountImageIntoNode(markup, container, wrapperInstance, shouldReuseMarkup, transaction); |
|
} |
|
|
|
/** |
|
* Batched mount. |
|
* |
|
* @param {ReactComponent} componentInstance The instance to mount. |
|
* @param {DOMElement} container DOM element to mount into. |
|
* @param {boolean} shouldReuseMarkup If true, do not insert markup |
|
*/ |
|
function batchedMountComponentIntoNode(componentInstance, container, shouldReuseMarkup, context) { |
|
var transaction = ReactUpdates.ReactReconcileTransaction.getPooled( |
|
/* useCreateElement */ |
|
!shouldReuseMarkup && ReactDOMFeatureFlags.useCreateElement); |
|
transaction.perform(mountComponentIntoNode, null, componentInstance, container, transaction, shouldReuseMarkup, context); |
|
ReactUpdates.ReactReconcileTransaction.release(transaction); |
|
} |
|
|
|
/** |
|
* 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} |
|
*/ |
|
function unmountComponentFromNode(instance, container, safely) { |
|
if ("development" !== 'production') { |
|
ReactInstrumentation.debugTool.onBeginFlush(); |
|
} |
|
ReactReconciler.unmountComponent(instance, safely); |
|
if ("development" !== 'production') { |
|
ReactInstrumentation.debugTool.onEndFlush(); |
|
} |
|
|
|
if (container.nodeType === DOC_NODE_TYPE) { |
|
container = container.documentElement; |
|
} |
|
|
|
// http://jsperf.com/emptying-a-node |
|
while (container.lastChild) { |
|
container.removeChild(container.lastChild); |
|
} |
|
} |
|
|
|
/** |
|
* True if the supplied DOM node has a direct React-rendered child that is |
|
* not a React root element. Useful for warning in `render`, |
|
* `unmountComponentAtNode`, etc. |
|
* |
|
* @param {?DOMElement} node The candidate DOM node. |
|
* @return {boolean} True if the DOM element contains a direct child that was |
|
* rendered by React but is not a root element. |
|
* @internal |
|
*/ |
|
function hasNonRootReactChild(container) { |
|
var rootEl = getReactRootElementInContainer(container); |
|
if (rootEl) { |
|
var inst = ReactDOMComponentTree.getInstanceFromNode(rootEl); |
|
return !!(inst && inst._hostParent); |
|
} |
|
} |
|
|
|
/** |
|
* True if the supplied DOM node is a React DOM element and |
|
* it has been rendered by another copy of React. |
|
* |
|
* @param {?DOMElement} node The candidate DOM node. |
|
* @return {boolean} True if the DOM has been rendered by another copy of React |
|
* @internal |
|
*/ |
|
function nodeIsRenderedByOtherInstance(container) { |
|
var rootEl = getReactRootElementInContainer(container); |
|
return !!(rootEl && isReactNode(rootEl) && !ReactDOMComponentTree.getInstanceFromNode(rootEl)); |
|
} |
|
|
|
/** |
|
* True if the supplied DOM node is a valid node element. |
|
* |
|
* @param {?DOMElement} node The candidate DOM node. |
|
* @return {boolean} True if the DOM is a valid DOM node. |
|
* @internal |
|
*/ |
|
function isValidContainer(node) { |
|
return !!(node && (node.nodeType === ELEMENT_NODE_TYPE || node.nodeType === DOC_NODE_TYPE || node.nodeType === DOCUMENT_FRAGMENT_NODE_TYPE)); |
|
} |
|
|
|
/** |
|
* True if the supplied DOM node is a valid React node element. |
|
* |
|
* @param {?DOMElement} node The candidate DOM node. |
|
* @return {boolean} True if the DOM is a valid React DOM node. |
|
* @internal |
|
*/ |
|
function isReactNode(node) { |
|
return isValidContainer(node) && (node.hasAttribute(ROOT_ATTR_NAME) || node.hasAttribute(ATTR_NAME)); |
|
} |
|
|
|
function getHostRootInstanceInContainer(container) { |
|
var rootEl = getReactRootElementInContainer(container); |
|
var prevHostInstance = rootEl && ReactDOMComponentTree.getInstanceFromNode(rootEl); |
|
return prevHostInstance && !prevHostInstance._hostParent ? prevHostInstance : null; |
|
} |
|
|
|
function getTopLevelWrapperInContainer(container) { |
|
var root = getHostRootInstanceInContainer(container); |
|
return root ? root._hostContainerInfo._topLevelWrapper : null; |
|
} |
|
|
|
/** |
|
* Temporary (?) hack so that we can store all top-level pending updates on |
|
* composites instead of having to worry about different types of components |
|
* here. |
|
*/ |
|
var topLevelRootCounter = 1; |
|
var TopLevelWrapper = function () { |
|
this.rootID = topLevelRootCounter++; |
|
}; |
|
TopLevelWrapper.prototype.isReactComponent = {}; |
|
if ("development" !== 'production') { |
|
TopLevelWrapper.displayName = 'TopLevelWrapper'; |
|
} |
|
TopLevelWrapper.prototype.render = function () { |
|
return this.props.child; |
|
}; |
|
TopLevelWrapper.isReactTopLevelWrapper = true; |
|
|
|
/** |
|
* Mounting is the process of initializing a React component by creating its |
|
* representative DOM elements and inserting them into a supplied `container`. |
|
* Any prior content inside `container` is destroyed in the process. |
|
* |
|
* ReactMount.render( |
|
* 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 = { |
|
|
|
TopLevelWrapper: TopLevelWrapper, |
|
|
|
/** |
|
* Used by devtools. The keys are not important. |
|
*/ |
|
_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 {ReactElement} nextElement component instance to render |
|
* @param {DOMElement} container container to render into |
|
* @param {?function} callback function triggered on completion |
|
*/ |
|
_updateRootComponent: function (prevComponent, nextElement, nextContext, container, callback) { |
|
ReactMount.scrollMonitor(container, function () { |
|
ReactUpdateQueue.enqueueElementInternal(prevComponent, nextElement, nextContext); |
|
if (callback) { |
|
ReactUpdateQueue.enqueueCallbackInternal(prevComponent, callback); |
|
} |
|
}); |
|
|
|
return prevComponent; |
|
}, |
|
|
|
/** |
|
* Render a new component into the DOM. Hooked by hooks! |
|
* |
|
* @param {ReactElement} nextElement element to render |
|
* @param {DOMElement} container container to render into |
|
* @param {boolean} shouldReuseMarkup if we should skip the markup insertion |
|
* @return {ReactComponent} nextComponent |
|
*/ |
|
_renderNewRootComponent: function (nextElement, container, shouldReuseMarkup, context) { |
|
// Various parts of our code (such as ReactCompositeComponent's |
|
// _renderValidatedComponent) assume that calls to render aren't nested; |
|
// verify that that's the case. |
|
"development" !== 'production' ? warning(ReactCurrentOwner.current == null, '_renderNewRootComponent(): Render methods should be a pure function ' + 'of props and state; triggering nested component updates from ' + 'render is not allowed. If necessary, trigger nested updates in ' + 'componentDidUpdate. Check the render method of %s.', ReactCurrentOwner.current && ReactCurrentOwner.current.getName() || 'ReactCompositeComponent') : void 0; |
|
|
|
!isValidContainer(container) ? "development" !== 'production' ? invariant(false, '_registerComponent(...): Target container is not a DOM element.') : _prodInvariant('37') : void 0; |
|
|
|
ReactBrowserEventEmitter.ensureScrollValueMonitoring(); |
|
var componentInstance = instantiateReactComponent(nextElement, false); |
|
|
|
// The initial render is synchronous but any updates that happen during |
|
// rendering, in componentWillMount or componentDidMount, will be batched |
|
// according to the current batching strategy. |
|
|
|
ReactUpdates.batchedUpdates(batchedMountComponentIntoNode, componentInstance, container, shouldReuseMarkup, context); |
|
|
|
var wrapperID = componentInstance._instance.rootID; |
|
instancesByReactRootID[wrapperID] = componentInstance; |
|
|
|
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} parentComponent The conceptual parent of this render tree. |
|
* @param {ReactElement} nextElement Component element to render. |
|
* @param {DOMElement} container DOM element to render into. |
|
* @param {?function} callback function triggered on completion |
|
* @return {ReactComponent} Component instance rendered in `container`. |
|
*/ |
|
renderSubtreeIntoContainer: function (parentComponent, nextElement, container, callback) { |
|
!(parentComponent != null && ReactInstanceMap.has(parentComponent)) ? "development" !== 'production' ? invariant(false, 'parentComponent must be a valid React Component') : _prodInvariant('38') : void 0; |
|
return ReactMount._renderSubtreeIntoContainer(parentComponent, nextElement, container, callback); |
|
}, |
|
|
|
_renderSubtreeIntoContainer: function (parentComponent, nextElement, container, callback) { |
|
ReactUpdateQueue.validateCallback(callback, 'ReactDOM.render'); |
|
!React.isValidElement(nextElement) ? "development" !== 'production' ? invariant(false, 'ReactDOM.render(): Invalid component element.%s', typeof nextElement === 'string' ? ' Instead of passing a string like \'div\', pass ' + 'React.createElement(\'div\') or <div />.' : typeof nextElement === 'function' ? ' Instead of passing a class like Foo, pass ' + 'React.createElement(Foo) or <Foo />.' : |
|
// Check if it quacks like an element |
|
nextElement != null && nextElement.props !== undefined ? ' This may be caused by unintentionally loading two independent ' + 'copies of React.' : '') : _prodInvariant('39', typeof nextElement === 'string' ? ' Instead of passing a string like \'div\', pass ' + 'React.createElement(\'div\') or <div />.' : typeof nextElement === 'function' ? ' Instead of passing a class like Foo, pass ' + 'React.createElement(Foo) or <Foo />.' : nextElement != null && nextElement.props !== undefined ? ' This may be caused by unintentionally loading two independent ' + 'copies of React.' : '') : void 0; |
|
|
|
"development" !== 'production' ? warning(!container || !container.tagName || container.tagName.toUpperCase() !== 'BODY', 'render(): Rendering components directly into document.body is ' + 'discouraged, since its children are often manipulated by third-party ' + 'scripts and browser extensions. This may lead to subtle ' + 'reconciliation issues. Try rendering into a container element created ' + 'for your app.') : void 0; |
|
|
|
var nextWrappedElement = React.createElement(TopLevelWrapper, { child: nextElement }); |
|
|
|
var nextContext; |
|
if (parentComponent) { |
|
var parentInst = ReactInstanceMap.get(parentComponent); |
|
nextContext = parentInst._processChildContext(parentInst._context); |
|
} else { |
|
nextContext = emptyObject; |
|
} |
|
|
|
var prevComponent = getTopLevelWrapperInContainer(container); |
|
|
|
if (prevComponent) { |
|
var prevWrappedElement = prevComponent._currentElement; |
|
var prevElement = prevWrappedElement.props.child; |
|
if (shouldUpdateReactComponent(prevElement, nextElement)) { |
|
var publicInst = prevComponent._renderedComponent.getPublicInstance(); |
|
var updatedCallback = callback && function () { |
|
callback.call(publicInst); |
|
}; |
|
ReactMount._updateRootComponent(prevComponent, nextWrappedElement, nextContext, container, updatedCallback); |
|
return publicInst; |
|
} else { |
|
ReactMount.unmountComponentAtNode(container); |
|
} |
|
} |
|
|
|
var reactRootElement = getReactRootElementInContainer(container); |
|
var containerHasReactMarkup = reactRootElement && !!internalGetID(reactRootElement); |
|
var containerHasNonRootReactChild = hasNonRootReactChild(container); |
|
|
|
if ("development" !== 'production') { |
|
"development" !== 'production' ? warning(!containerHasNonRootReactChild, 'render(...): Replacing React-rendered children with a new root ' + 'component. If you intended to update the children of this node, ' + 'you should instead have the existing children update their state ' + 'and render the new components instead of calling ReactDOM.render.') : void 0; |
|
|
|
if (!containerHasReactMarkup || reactRootElement.nextSibling) { |
|
var rootElementSibling = reactRootElement; |
|
while (rootElementSibling) { |
|
if (internalGetID(rootElementSibling)) { |
|
"development" !== 'production' ? warning(false, 'render(): Target node has markup rendered by React, but there ' + 'are unrelated nodes as well. This is most commonly caused by ' + 'white-space inserted around server-rendered markup.') : void 0; |
|
break; |
|
} |
|
rootElementSibling = rootElementSibling.nextSibling; |
|
} |
|
} |
|
} |
|
|
|
var shouldReuseMarkup = containerHasReactMarkup && !prevComponent && !containerHasNonRootReactChild; |
|
var component = ReactMount._renderNewRootComponent(nextWrappedElement, container, shouldReuseMarkup, nextContext)._renderedComponent.getPublicInstance(); |
|
if (callback) { |
|
callback.call(component); |
|
} |
|
return component; |
|
}, |
|
|
|
/** |
|
* Renders a React component into the DOM in the supplied `container`. |
|
* See https://facebook.github.io/react/docs/top-level-api.html#reactdom.render |
|
* |
|
* 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 {ReactElement} nextElement Component element to render. |
|
* @param {DOMElement} container DOM element to render into. |
|
* @param {?function} callback function triggered on completion |
|
* @return {ReactComponent} Component instance rendered in `container`. |
|
*/ |
|
render: function (nextElement, container, callback) { |
|
return ReactMount._renderSubtreeIntoContainer(null, nextElement, container, callback); |
|
}, |
|
|
|
/** |
|
* Unmounts and destroys the React component rendered in the `container`. |
|
* See https://facebook.github.io/react/docs/top-level-api.html#reactdom.unmountcomponentatnode |
|
* |
|
* @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) { |
|
// Various parts of our code (such as ReactCompositeComponent's |
|
// _renderValidatedComponent) assume that calls to render aren't nested; |
|
// verify that that's the case. (Strictly speaking, unmounting won't cause a |
|
// render but we still don't expect to be in a render call here.) |
|
"development" !== 'production' ? warning(ReactCurrentOwner.current == null, 'unmountComponentAtNode(): Render methods should be a pure function ' + 'of props and state; triggering nested component updates from render ' + 'is not allowed. If necessary, trigger nested updates in ' + 'componentDidUpdate. Check the render method of %s.', ReactCurrentOwner.current && ReactCurrentOwner.current.getName() || 'ReactCompositeComponent') : void 0; |
|
|
|
!isValidContainer(container) ? "development" !== 'production' ? invariant(false, 'unmountComponentAtNode(...): Target container is not a DOM element.') : _prodInvariant('40') : void 0; |
|
|
|
if ("development" !== 'production') { |
|
"development" !== 'production' ? warning(!nodeIsRenderedByOtherInstance(container), 'unmountComponentAtNode(): The node you\'re attempting to unmount ' + 'was rendered by another copy of React.') : void 0; |
|
} |
|
|
|
var prevComponent = getTopLevelWrapperInContainer(container); |
|
if (!prevComponent) { |
|
// Check if the node being unmounted was rendered by React, but isn't a |
|
// root node. |
|
var containerHasNonRootReactChild = hasNonRootReactChild(container); |
|
|
|
// Check if the container itself is a React root node. |
|
var isContainerReactRoot = container.nodeType === 1 && container.hasAttribute(ROOT_ATTR_NAME); |
|
|
|
if ("development" !== 'production') { |
|
"development" !== 'production' ? warning(!containerHasNonRootReactChild, 'unmountComponentAtNode(): The node you\'re attempting to unmount ' + 'was rendered by React and is not a top-level container. %s', isContainerReactRoot ? 'You may have accidentally passed in a React root node instead ' + 'of its container.' : 'Instead, have the parent component update its state and ' + 'rerender in order to remove this component.') : void 0; |
|
} |
|
|
|
return false; |
|
} |
|
delete instancesByReactRootID[prevComponent._instance.rootID]; |
|
ReactUpdates.batchedUpdates(unmountComponentFromNode, prevComponent, container, false); |
|
return true; |
|
}, |
|
|
|
_mountImageIntoNode: function (markup, container, instance, shouldReuseMarkup, transaction) { |
|
!isValidContainer(container) ? "development" !== 'production' ? invariant(false, 'mountComponentIntoNode(...): Target container is not valid.') : _prodInvariant('41') : void 0; |
|
|
|
if (shouldReuseMarkup) { |
|
var rootElement = getReactRootElementInContainer(container); |
|
if (ReactMarkupChecksum.canReuseMarkup(markup, rootElement)) { |
|
ReactDOMComponentTree.precacheNode(instance, rootElement); |
|
return; |
|
} else { |
|
var checksum = rootElement.getAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME); |
|
rootElement.removeAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME); |
|
|
|
var rootMarkup = rootElement.outerHTML; |
|
rootElement.setAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME, checksum); |
|
|
|
var normalizedMarkup = markup; |
|
if ("development" !== 'production') { |
|
// because rootMarkup is retrieved from the DOM, various normalizations |
|
// will have occurred which will not be present in `markup`. Here, |
|
// insert markup into a <div> or <iframe> depending on the container |
|
// type to perform the same normalizations before comparing. |
|
var normalizer; |
|
if (container.nodeType === ELEMENT_NODE_TYPE) { |
|
normalizer = document.createElement('div'); |
|
normalizer.innerHTML = markup; |
|
normalizedMarkup = normalizer.innerHTML; |
|
} else { |
|
normalizer = document.createElement('iframe'); |
|
document.body.appendChild(normalizer); |
|
normalizer.contentDocument.write(markup); |
|
normalizedMarkup = normalizer.contentDocument.documentElement.outerHTML; |
|
document.body.removeChild(normalizer); |
|
} |
|
} |
|
|
|
var diffIndex = firstDifferenceIndex(normalizedMarkup, rootMarkup); |
|
var difference = ' (client) ' + normalizedMarkup.substring(diffIndex - 20, diffIndex + 20) + '\n (server) ' + rootMarkup.substring(diffIndex - 20, diffIndex + 20); |
|
|
|
!(container.nodeType !== DOC_NODE_TYPE) ? "development" !== 'production' ? invariant(false, '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:\n%s', difference) : _prodInvariant('42', difference) : void 0; |
|
|
|
if ("development" !== 'production') { |
|
"development" !== 'production' ? warning(false, 'React attempted to 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:\n%s', difference) : void 0; |
|
} |
|
} |
|
} |
|
|
|
!(container.nodeType !== DOC_NODE_TYPE) ? "development" !== 'production' ? invariant(false, '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 ReactDOMServer.renderToString() for server rendering.') : _prodInvariant('43') : void 0; |
|
|
|
if (transaction.useCreateElement) { |
|
while (container.lastChild) { |
|
container.removeChild(container.lastChild); |
|
} |
|
DOMLazyTree.insertTreeBefore(container, markup, null); |
|
} else { |
|
setInnerHTML(container, markup); |
|
ReactDOMComponentTree.precacheNode(instance, container.firstChild); |
|
} |
|
|
|
if ("development" !== 'production') { |
|
var hostNode = ReactDOMComponentTree.getInstanceFromNode(container.firstChild); |
|
if (hostNode._debugID !== 0) { |
|
ReactInstrumentation.debugTool.onHostOperation({ |
|
instanceID: hostNode._debugID, |
|
type: 'mount', |
|
payload: markup.toString() |
|
}); |
|
} |
|
} |
|
} |
|
}; |
|
|
|
module.exports = ReactMount; |
|
},{"11":11,"121":121,"125":125,"127":127,"129":129,"133":133,"134":134,"143":143,"150":150,"157":157,"26":26,"34":34,"35":35,"37":37,"58":58,"63":63,"64":64,"66":66,"75":75,"81":81,"82":82,"9":9}],68:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125); |
|
|
|
var ReactComponentEnvironment = _dereq_(29); |
|
var ReactInstanceMap = _dereq_(63); |
|
var ReactInstrumentation = _dereq_(64); |
|
|
|
var ReactCurrentOwner = _dereq_(133); |
|
var ReactReconciler = _dereq_(75); |
|
var ReactChildReconciler = _dereq_(27); |
|
|
|
var emptyFunction = _dereq_(142); |
|
var flattenChildren = _dereq_(109); |
|
var invariant = _dereq_(150); |
|
|
|
/** |
|
* Make an update for markup to be rendered and inserted at a supplied index. |
|
* |
|
* @param {string} markup Markup that renders into an element. |
|
* @param {number} toIndex Destination index. |
|
* @private |
|
*/ |
|
function makeInsertMarkup(markup, afterNode, toIndex) { |
|
// NOTE: Null values reduce hidden classes. |
|
return { |
|
type: 'INSERT_MARKUP', |
|
content: markup, |
|
fromIndex: null, |
|
fromNode: null, |
|
toIndex: toIndex, |
|
afterNode: afterNode |
|
}; |
|
} |
|
|
|
/** |
|
* Make an update for moving an existing element to another index. |
|
* |
|
* @param {number} fromIndex Source index of the existing element. |
|
* @param {number} toIndex Destination index of the element. |
|
* @private |
|
*/ |
|
function makeMove(child, afterNode, toIndex) { |
|
// NOTE: Null values reduce hidden classes. |
|
return { |
|
type: 'MOVE_EXISTING', |
|
content: null, |
|
fromIndex: child._mountIndex, |
|
fromNode: ReactReconciler.getHostNode(child), |
|
toIndex: toIndex, |
|
afterNode: afterNode |
|
}; |
|
} |
|
|
|
/** |
|
* Make an update for removing an element at an index. |
|
* |
|
* @param {number} fromIndex Index of the element to remove. |
|
* @private |
|
*/ |
|
function makeRemove(child, node) { |
|
// NOTE: Null values reduce hidden classes. |
|
return { |
|
type: 'REMOVE_NODE', |
|
content: null, |
|
fromIndex: child._mountIndex, |
|
fromNode: node, |
|
toIndex: null, |
|
afterNode: null |
|
}; |
|
} |
|
|
|
/** |
|
* Make an update for setting the markup of a node. |
|
* |
|
* @param {string} markup Markup that renders into an element. |
|
* @private |
|
*/ |
|
function makeSetMarkup(markup) { |
|
// NOTE: Null values reduce hidden classes. |
|
return { |
|
type: 'SET_MARKUP', |
|
content: markup, |
|
fromIndex: null, |
|
fromNode: null, |
|
toIndex: null, |
|
afterNode: null |
|
}; |
|
} |
|
|
|
/** |
|
* Make an update for setting the text content. |
|
* |
|
* @param {string} textContent Text content to set. |
|
* @private |
|
*/ |
|
function makeTextContent(textContent) { |
|
// NOTE: Null values reduce hidden classes. |
|
return { |
|
type: 'TEXT_CONTENT', |
|
content: textContent, |
|
fromIndex: null, |
|
fromNode: null, |
|
toIndex: null, |
|
afterNode: null |
|
}; |
|
} |
|
|
|
/** |
|
* Push an update, if any, onto the queue. Creates a new queue if none is |
|
* passed and always returns the queue. Mutative. |
|
*/ |
|
function enqueue(queue, update) { |
|
if (update) { |
|
queue = queue || []; |
|
queue.push(update); |
|
} |
|
return queue; |
|
} |
|
|
|
/** |
|
* Processes any enqueued updates. |
|
* |
|
* @private |
|
*/ |
|
function processQueue(inst, updateQueue) { |
|
ReactComponentEnvironment.processChildrenUpdates(inst, updateQueue); |
|
} |
|
|
|
var setChildrenForInstrumentation = emptyFunction; |
|
if ("development" !== 'production') { |
|
var getDebugID = function (inst) { |
|
if (!inst._debugID) { |
|
// Check for ART-like instances. TODO: This is silly/gross. |
|
var internal; |
|
if (internal = ReactInstanceMap.get(inst)) { |
|
inst = internal; |
|
} |
|
} |
|
return inst._debugID; |
|
}; |
|
setChildrenForInstrumentation = function (children) { |
|
var debugID = getDebugID(this); |
|
// TODO: React Native empty components are also multichild. |
|
// This means they still get into this method but don't have _debugID. |
|
if (debugID !== 0) { |
|
ReactInstrumentation.debugTool.onSetChildren(debugID, children ? Object.keys(children).map(function (key) { |
|
return children[key]._debugID; |
|
}) : []); |
|
} |
|
}; |
|
} |
|
|
|
/** |
|
* 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: { |
|
|
|
_reconcilerInstantiateChildren: function (nestedChildren, transaction, context) { |
|
if ("development" !== 'production') { |
|
var selfDebugID = getDebugID(this); |
|
if (this._currentElement) { |
|
try { |
|
ReactCurrentOwner.current = this._currentElement._owner; |
|
return ReactChildReconciler.instantiateChildren(nestedChildren, transaction, context, selfDebugID); |
|
} finally { |
|
ReactCurrentOwner.current = null; |
|
} |
|
} |
|
} |
|
return ReactChildReconciler.instantiateChildren(nestedChildren, transaction, context); |
|
}, |
|
|
|
_reconcilerUpdateChildren: function (prevChildren, nextNestedChildrenElements, mountImages, removedNodes, transaction, context) { |
|
var nextChildren; |
|
var selfDebugID = 0; |
|
if ("development" !== 'production') { |
|
selfDebugID = getDebugID(this); |
|
if (this._currentElement) { |
|
try { |
|
ReactCurrentOwner.current = this._currentElement._owner; |
|
nextChildren = flattenChildren(nextNestedChildrenElements, selfDebugID); |
|
} finally { |
|
ReactCurrentOwner.current = null; |
|
} |
|
ReactChildReconciler.updateChildren(prevChildren, nextChildren, mountImages, removedNodes, transaction, this, this._hostContainerInfo, context, selfDebugID); |
|
return nextChildren; |
|
} |
|
} |
|
nextChildren = flattenChildren(nextNestedChildrenElements, selfDebugID); |
|
ReactChildReconciler.updateChildren(prevChildren, nextChildren, mountImages, removedNodes, transaction, this, this._hostContainerInfo, context, selfDebugID); |
|
return nextChildren; |
|
}, |
|
|
|
/** |
|
* 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, context) { |
|
var children = this._reconcilerInstantiateChildren(nestedChildren, transaction, context); |
|
this._renderedChildren = children; |
|
|
|
var mountImages = []; |
|
var index = 0; |
|
for (var name in children) { |
|
if (children.hasOwnProperty(name)) { |
|
var child = children[name]; |
|
var selfDebugID = 0; |
|
if ("development" !== 'production') { |
|
selfDebugID = getDebugID(this); |
|
} |
|
var mountImage = ReactReconciler.mountComponent(child, transaction, this, this._hostContainerInfo, context, selfDebugID); |
|
child._mountIndex = index++; |
|
mountImages.push(mountImage); |
|
} |
|
} |
|
|
|
if ("development" !== 'production') { |
|
setChildrenForInstrumentation.call(this, children); |
|
} |
|
|
|
return mountImages; |
|
}, |
|
|
|
/** |
|
* Replaces any rendered children with a text content string. |
|
* |
|
* @param {string} nextContent String of content. |
|
* @internal |
|
*/ |
|
updateTextContent: function (nextContent) { |
|
var prevChildren = this._renderedChildren; |
|
// Remove any rendered children. |
|
ReactChildReconciler.unmountChildren(prevChildren, false); |
|
for (var name in prevChildren) { |
|
if (prevChildren.hasOwnProperty(name)) { |
|
!false ? "development" !== 'production' ? invariant(false, 'updateTextContent called on non-empty component.') : _prodInvariant('118') : void 0; |
|
} |
|
} |
|
// Set new text content. |
|
var updates = [makeTextContent(nextContent)]; |
|
processQueue(this, updates); |
|
}, |
|
|
|
/** |
|
* Replaces any rendered children with a markup string. |
|
* |
|
* @param {string} nextMarkup String of markup. |
|
* @internal |
|
*/ |
|
updateMarkup: function (nextMarkup) { |
|
var prevChildren = this._renderedChildren; |
|
// Remove any rendered children. |
|
ReactChildReconciler.unmountChildren(prevChildren, false); |
|
for (var name in prevChildren) { |
|
if (prevChildren.hasOwnProperty(name)) { |
|
!false ? "development" !== 'production' ? invariant(false, 'updateTextContent called on non-empty component.') : _prodInvariant('118') : void 0; |
|
} |
|
} |
|
var updates = [makeSetMarkup(nextMarkup)]; |
|
processQueue(this, updates); |
|
}, |
|
|
|
/** |
|
* Updates the rendered children with new children. |
|
* |
|
* @param {?object} nextNestedChildrenElements Nested child element maps. |
|
* @param {ReactReconcileTransaction} transaction |
|
* @internal |
|
*/ |
|
updateChildren: function (nextNestedChildrenElements, transaction, context) { |
|
// Hook used by React ART |
|
this._updateChildren(nextNestedChildrenElements, transaction, context); |
|
}, |
|
|
|
/** |
|
* @param {?object} nextNestedChildrenElements Nested child element maps. |
|
* @param {ReactReconcileTransaction} transaction |
|
* @final |
|
* @protected |
|
*/ |
|
_updateChildren: function (nextNestedChildrenElements, transaction, context) { |
|
var prevChildren = this._renderedChildren; |
|
var removedNodes = {}; |
|
var mountImages = []; |
|
var nextChildren = this._reconcilerUpdateChildren(prevChildren, nextNestedChildrenElements, mountImages, removedNodes, transaction, context); |
|
if (!nextChildren && !prevChildren) { |
|
return; |
|
} |
|
var updates = null; |
|
var name; |
|
// `nextIndex` will increment for each child in `nextChildren`, but |
|
// `lastIndex` will be the last index visited in `prevChildren`. |
|
var nextIndex = 0; |
|
var lastIndex = 0; |
|
// `nextMountIndex` will increment for each newly mounted child. |
|
var nextMountIndex = 0; |
|
var lastPlacedNode = null; |
|
for (name in nextChildren) { |
|
if (!nextChildren.hasOwnProperty(name)) { |
|
continue; |
|
} |
|
var prevChild = prevChildren && prevChildren[name]; |
|
var nextChild = nextChildren[name]; |
|
if (prevChild === nextChild) { |
|
updates = enqueue(updates, this.moveChild(prevChild, lastPlacedNode, nextIndex, lastIndex)); |
|
lastIndex = Math.max(prevChild._mountIndex, lastIndex); |
|
prevChild._mountIndex = nextIndex; |
|
} else { |
|
if (prevChild) { |
|
// Update `lastIndex` before `_mountIndex` gets unset by unmounting. |
|
lastIndex = Math.max(prevChild._mountIndex, lastIndex); |
|
// The `removedNodes` loop below will actually remove the child. |
|
} |
|
// The child must be instantiated before it's mounted. |
|
updates = enqueue(updates, this._mountChildAtIndex(nextChild, mountImages[nextMountIndex], lastPlacedNode, nextIndex, transaction, context)); |
|
nextMountIndex++; |
|
} |
|
nextIndex++; |
|
lastPlacedNode = ReactReconciler.getHostNode(nextChild); |
|
} |
|
// Remove children that are no longer present. |
|
for (name in removedNodes) { |
|
if (removedNodes.hasOwnProperty(name)) { |
|
updates = enqueue(updates, this._unmountChild(prevChildren[name], removedNodes[name])); |
|
} |
|
} |
|
if (updates) { |
|
processQueue(this, updates); |
|
} |
|
this._renderedChildren = nextChildren; |
|
|
|
if ("development" !== 'production') { |
|
setChildrenForInstrumentation.call(this, nextChildren); |
|
} |
|
}, |
|
|
|
/** |
|
* Unmounts all rendered children. This should be used to clean up children |
|
* when this component is unmounted. It does not actually perform any |
|
* backend operations. |
|
* |
|
* @internal |
|
*/ |
|
unmountChildren: function (safely) { |
|
var renderedChildren = this._renderedChildren; |
|
ReactChildReconciler.unmountChildren(renderedChildren, safely); |
|
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, afterNode, 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) { |
|
return makeMove(child, afterNode, toIndex); |
|
} |
|
}, |
|
|
|
/** |
|
* Creates a child component. |
|
* |
|
* @param {ReactComponent} child Component to create. |
|
* @param {string} mountImage Markup to insert. |
|
* @protected |
|
*/ |
|
createChild: function (child, afterNode, mountImage) { |
|
return makeInsertMarkup(mountImage, afterNode, child._mountIndex); |
|
}, |
|
|
|
/** |
|
* Removes a child component. |
|
* |
|
* @param {ReactComponent} child Child to remove. |
|
* @protected |
|
*/ |
|
removeChild: function (child, node) { |
|
return makeRemove(child, node); |
|
}, |
|
|
|
/** |
|
* 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 |
|
*/ |
|
_mountChildAtIndex: function (child, mountImage, afterNode, index, transaction, context) { |
|
child._mountIndex = index; |
|
return this.createChild(child, afterNode, mountImage); |
|
}, |
|
|
|
/** |
|
* Unmounts a rendered child. |
|
* |
|
* NOTE: This is part of `updateChildren` and is here for readability. |
|
* |
|
* @param {ReactComponent} child Component to unmount. |
|
* @private |
|
*/ |
|
_unmountChild: function (child, node) { |
|
var update = this.removeChild(child, node); |
|
child._mountIndex = null; |
|
return update; |
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
module.exports = ReactMultiChild; |
|
},{"109":109,"125":125,"133":133,"142":142,"150":150,"27":27,"29":29,"63":63,"64":64,"75":75}],69:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125); |
|
|
|
var React = _dereq_(134); |
|
|
|
var invariant = _dereq_(150); |
|
|
|
var ReactNodeTypes = { |
|
HOST: 0, |
|
COMPOSITE: 1, |
|
EMPTY: 2, |
|
|
|
getType: function (node) { |
|
if (node === null || node === false) { |
|
return ReactNodeTypes.EMPTY; |
|
} else if (React.isValidElement(node)) { |
|
if (typeof node.type === 'function') { |
|
return ReactNodeTypes.COMPOSITE; |
|
} else { |
|
return ReactNodeTypes.HOST; |
|
} |
|
} |
|
!false ? "development" !== 'production' ? invariant(false, 'Unexpected node: %s', node) : _prodInvariant('26', node) : void 0; |
|
} |
|
}; |
|
|
|
module.exports = ReactNodeTypes; |
|
},{"125":125,"134":134,"150":150}],70:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125); |
|
|
|
var invariant = _dereq_(150); |
|
|
|
/** |
|
* @param {?object} object |
|
* @return {boolean} True if `object` is a valid owner. |
|
* @final |
|
*/ |
|
function isValidOwner(object) { |
|
return !!(object && typeof object.attachRef === 'function' && typeof object.detachRef === 'function'); |
|
} |
|
|
|
/** |
|
* 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 = { |
|
/** |
|
* 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) { |
|
!isValidOwner(owner) ? "development" !== 'production' ? invariant(false, 'addComponentAsRefTo(...): Only a ReactOwner can have refs. You might be adding a ref to a component that was not created inside a component\'s `render` method, or you have multiple copies of React loaded (details: https://fb.me/react-refs-must-have-owner).') : _prodInvariant('119') : void 0; |
|
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) { |
|
!isValidOwner(owner) ? "development" !== 'production' ? invariant(false, 'removeComponentAsRefFrom(...): Only a ReactOwner can have refs. You might be removing a ref to a component that was not created inside a component\'s `render` method, or you have multiple copies of React loaded (details: https://fb.me/react-refs-must-have-owner).') : _prodInvariant('120') : void 0; |
|
var ownerPublicInstance = owner.getPublicInstance(); |
|
// Check that `component`'s owner is still alive and that `component` is still the current ref |
|
// because we do not want to detach the ref if another component stole it. |
|
if (ownerPublicInstance && ownerPublicInstance.refs[ref] === component.getPublicInstance()) { |
|
owner.detachRef(ref); |
|
} |
|
} |
|
|
|
}; |
|
|
|
module.exports = ReactOwner; |
|
},{"125":125,"150":150}],71:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2016-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _assign = _dereq_(158); |
|
|
|
var _extends = _assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; |
|
|
|
var ReactDebugTool = _dereq_(50); |
|
var warning = _dereq_(157); |
|
var alreadyWarned = false; |
|
|
|
function roundFloat(val) { |
|
var base = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2; |
|
|
|
var n = Math.pow(10, base); |
|
return Math.floor(val * n) / n; |
|
} |
|
|
|
// Flow type definition of console.table is too strict right now, see |
|
// https://github.com/facebook/flow/pull/2353 for updates |
|
function consoleTable(table) { |
|
console.table(table); |
|
} |
|
|
|
function warnInProduction() { |
|
if (alreadyWarned) { |
|
return; |
|
} |
|
alreadyWarned = true; |
|
if (typeof console !== 'undefined') { |
|
console.error('ReactPerf is not supported in the production builds of React. ' + 'To collect measurements, please use the development build of React instead.'); |
|
} |
|
} |
|
|
|
function getLastMeasurements() { |
|
if (!("development" !== 'production')) { |
|
warnInProduction(); |
|
return []; |
|
} |
|
|
|
return ReactDebugTool.getFlushHistory(); |
|
} |
|
|
|
function getExclusive() { |
|
var flushHistory = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getLastMeasurements(); |
|
|
|
if (!("development" !== 'production')) { |
|
warnInProduction(); |
|
return []; |
|
} |
|
|
|
var aggregatedStats = {}; |
|
var affectedIDs = {}; |
|
|
|
function updateAggregatedStats(treeSnapshot, instanceID, timerType, applyUpdate) { |
|
var displayName = treeSnapshot[instanceID].displayName; |
|
|
|
var key = displayName; |
|
var stats = aggregatedStats[key]; |
|
if (!stats) { |
|
affectedIDs[key] = {}; |
|
stats = aggregatedStats[key] = { |
|
key: key, |
|
instanceCount: 0, |
|
counts: {}, |
|
durations: {}, |
|
totalDuration: 0 |
|
}; |
|
} |
|
if (!stats.durations[timerType]) { |
|
stats.durations[timerType] = 0; |
|
} |
|
if (!stats.counts[timerType]) { |
|
stats.counts[timerType] = 0; |
|
} |
|
affectedIDs[key][instanceID] = true; |
|
applyUpdate(stats); |
|
} |
|
|
|
flushHistory.forEach(function (flush) { |
|
var measurements = flush.measurements, |
|
treeSnapshot = flush.treeSnapshot; |
|
|
|
measurements.forEach(function (measurement) { |
|
var duration = measurement.duration, |
|
instanceID = measurement.instanceID, |
|
timerType = measurement.timerType; |
|
|
|
updateAggregatedStats(treeSnapshot, instanceID, timerType, function (stats) { |
|
stats.totalDuration += duration; |
|
stats.durations[timerType] += duration; |
|
stats.counts[timerType]++; |
|
}); |
|
}); |
|
}); |
|
|
|
return Object.keys(aggregatedStats).map(function (key) { |
|
return _extends({}, aggregatedStats[key], { |
|
instanceCount: Object.keys(affectedIDs[key]).length |
|
}); |
|
}).sort(function (a, b) { |
|
return b.totalDuration - a.totalDuration; |
|
}); |
|
} |
|
|
|
function getInclusive() { |
|
var flushHistory = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getLastMeasurements(); |
|
|
|
if (!("development" !== 'production')) { |
|
warnInProduction(); |
|
return []; |
|
} |
|
|
|
var aggregatedStats = {}; |
|
var affectedIDs = {}; |
|
|
|
function updateAggregatedStats(treeSnapshot, instanceID, applyUpdate) { |
|
var _treeSnapshot$instanc = treeSnapshot[instanceID], |
|
displayName = _treeSnapshot$instanc.displayName, |
|
ownerID = _treeSnapshot$instanc.ownerID; |
|
|
|
var owner = treeSnapshot[ownerID]; |
|
var key = (owner ? owner.displayName + ' > ' : '') + displayName; |
|
var stats = aggregatedStats[key]; |
|
if (!stats) { |
|
affectedIDs[key] = {}; |
|
stats = aggregatedStats[key] = { |
|
key: key, |
|
instanceCount: 0, |
|
inclusiveRenderDuration: 0, |
|
renderCount: 0 |
|
}; |
|
} |
|
affectedIDs[key][instanceID] = true; |
|
applyUpdate(stats); |
|
} |
|
|
|
var isCompositeByID = {}; |
|
flushHistory.forEach(function (flush) { |
|
var measurements = flush.measurements; |
|
|
|
measurements.forEach(function (measurement) { |
|
var instanceID = measurement.instanceID, |
|
timerType = measurement.timerType; |
|
|
|
if (timerType !== 'render') { |
|
return; |
|
} |
|
isCompositeByID[instanceID] = true; |
|
}); |
|
}); |
|
|
|
flushHistory.forEach(function (flush) { |
|
var measurements = flush.measurements, |
|
treeSnapshot = flush.treeSnapshot; |
|
|
|
measurements.forEach(function (measurement) { |
|
var duration = measurement.duration, |
|
instanceID = measurement.instanceID, |
|
timerType = measurement.timerType; |
|
|
|
if (timerType !== 'render') { |
|
return; |
|
} |
|
updateAggregatedStats(treeSnapshot, instanceID, function (stats) { |
|
stats.renderCount++; |
|
}); |
|
var nextParentID = instanceID; |
|
while (nextParentID) { |
|
// As we traverse parents, only count inclusive time towards composites. |
|
// We know something is a composite if its render() was called. |
|
if (isCompositeByID[nextParentID]) { |
|
updateAggregatedStats(treeSnapshot, nextParentID, function (stats) { |
|
stats.inclusiveRenderDuration += duration; |
|
}); |
|
} |
|
nextParentID = treeSnapshot[nextParentID].parentID; |
|
} |
|
}); |
|
}); |
|
|
|
return Object.keys(aggregatedStats).map(function (key) { |
|
return _extends({}, aggregatedStats[key], { |
|
instanceCount: Object.keys(affectedIDs[key]).length |
|
}); |
|
}).sort(function (a, b) { |
|
return b.inclusiveRenderDuration - a.inclusiveRenderDuration; |
|
}); |
|
} |
|
|
|
function getWasted() { |
|
var flushHistory = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getLastMeasurements(); |
|
|
|
if (!("development" !== 'production')) { |
|
warnInProduction(); |
|
return []; |
|
} |
|
|
|
var aggregatedStats = {}; |
|
var affectedIDs = {}; |
|
|
|
function updateAggregatedStats(treeSnapshot, instanceID, applyUpdate) { |
|
var _treeSnapshot$instanc2 = treeSnapshot[instanceID], |
|
displayName = _treeSnapshot$instanc2.displayName, |
|
ownerID = _treeSnapshot$instanc2.ownerID; |
|
|
|
var owner = treeSnapshot[ownerID]; |
|
var key = (owner ? owner.displayName + ' > ' : '') + displayName; |
|
var stats = aggregatedStats[key]; |
|
if (!stats) { |
|
affectedIDs[key] = {}; |
|
stats = aggregatedStats[key] = { |
|
key: key, |
|
instanceCount: 0, |
|
inclusiveRenderDuration: 0, |
|
renderCount: 0 |
|
}; |
|
} |
|
affectedIDs[key][instanceID] = true; |
|
applyUpdate(stats); |
|
} |
|
|
|
flushHistory.forEach(function (flush) { |
|
var measurements = flush.measurements, |
|
treeSnapshot = flush.treeSnapshot, |
|
operations = flush.operations; |
|
|
|
var isDefinitelyNotWastedByID = {}; |
|
|
|
// Find host components associated with an operation in this batch. |
|
// Mark all components in their parent tree as definitely not wasted. |
|
operations.forEach(function (operation) { |
|
var instanceID = operation.instanceID; |
|
|
|
var nextParentID = instanceID; |
|
while (nextParentID) { |
|
isDefinitelyNotWastedByID[nextParentID] = true; |
|
nextParentID = treeSnapshot[nextParentID].parentID; |
|
} |
|
}); |
|
|
|
// Find composite components that rendered in this batch. |
|
// These are potential candidates for being wasted renders. |
|
var renderedCompositeIDs = {}; |
|
measurements.forEach(function (measurement) { |
|
var instanceID = measurement.instanceID, |
|
timerType = measurement.timerType; |
|
|
|
if (timerType !== 'render') { |
|
return; |
|
} |
|
renderedCompositeIDs[instanceID] = true; |
|
}); |
|
|
|
measurements.forEach(function (measurement) { |
|
var duration = measurement.duration, |
|
instanceID = measurement.instanceID, |
|
timerType = measurement.timerType; |
|
|
|
if (timerType !== 'render') { |
|
return; |
|
} |
|
|
|
// If there was a DOM update below this component, or it has just been |
|
// mounted, its render() is not considered wasted. |
|
var updateCount = treeSnapshot[instanceID].updateCount; |
|
|
|
if (isDefinitelyNotWastedByID[instanceID] || updateCount === 0) { |
|
return; |
|
} |
|
|
|
// We consider this render() wasted. |
|
updateAggregatedStats(treeSnapshot, instanceID, function (stats) { |
|
stats.renderCount++; |
|
}); |
|
|
|
var nextParentID = instanceID; |
|
while (nextParentID) { |
|
// Any parents rendered during this batch are considered wasted |
|
// unless we previously marked them as dirty. |
|
var isWasted = renderedCompositeIDs[nextParentID] && !isDefinitelyNotWastedByID[nextParentID]; |
|
if (isWasted) { |
|
updateAggregatedStats(treeSnapshot, nextParentID, function (stats) { |
|
stats.inclusiveRenderDuration += duration; |
|
}); |
|
} |
|
nextParentID = treeSnapshot[nextParentID].parentID; |
|
} |
|
}); |
|
}); |
|
|
|
return Object.keys(aggregatedStats).map(function (key) { |
|
return _extends({}, aggregatedStats[key], { |
|
instanceCount: Object.keys(affectedIDs[key]).length |
|
}); |
|
}).sort(function (a, b) { |
|
return b.inclusiveRenderDuration - a.inclusiveRenderDuration; |
|
}); |
|
} |
|
|
|
function getOperations() { |
|
var flushHistory = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getLastMeasurements(); |
|
|
|
if (!("development" !== 'production')) { |
|
warnInProduction(); |
|
return []; |
|
} |
|
|
|
var stats = []; |
|
flushHistory.forEach(function (flush, flushIndex) { |
|
var operations = flush.operations, |
|
treeSnapshot = flush.treeSnapshot; |
|
|
|
operations.forEach(function (operation) { |
|
var instanceID = operation.instanceID, |
|
type = operation.type, |
|
payload = operation.payload; |
|
var _treeSnapshot$instanc3 = treeSnapshot[instanceID], |
|
displayName = _treeSnapshot$instanc3.displayName, |
|
ownerID = _treeSnapshot$instanc3.ownerID; |
|
|
|
var owner = treeSnapshot[ownerID]; |
|
var key = (owner ? owner.displayName + ' > ' : '') + displayName; |
|
|
|
stats.push({ |
|
flushIndex: flushIndex, |
|
instanceID: instanceID, |
|
key: key, |
|
type: type, |
|
ownerID: ownerID, |
|
payload: payload |
|
}); |
|
}); |
|
}); |
|
return stats; |
|
} |
|
|
|
function printExclusive(flushHistory) { |
|
if (!("development" !== 'production')) { |
|
warnInProduction(); |
|
return; |
|
} |
|
|
|
var stats = getExclusive(flushHistory); |
|
var table = stats.map(function (item) { |
|
var key = item.key, |
|
instanceCount = item.instanceCount, |
|
totalDuration = item.totalDuration; |
|
|
|
var renderCount = item.counts.render || 0; |
|
var renderDuration = item.durations.render || 0; |
|
return { |
|
'Component': key, |
|
'Total time (ms)': roundFloat(totalDuration), |
|
'Instance count': instanceCount, |
|
'Total render time (ms)': roundFloat(renderDuration), |
|
'Average render time (ms)': renderCount ? roundFloat(renderDuration / renderCount) : undefined, |
|
'Render count': renderCount, |
|
'Total lifecycle time (ms)': roundFloat(totalDuration - renderDuration) |
|
}; |
|
}); |
|
consoleTable(table); |
|
} |
|
|
|
function printInclusive(flushHistory) { |
|
if (!("development" !== 'production')) { |
|
warnInProduction(); |
|
return; |
|
} |
|
|
|
var stats = getInclusive(flushHistory); |
|
var table = stats.map(function (item) { |
|
var key = item.key, |
|
instanceCount = item.instanceCount, |
|
inclusiveRenderDuration = item.inclusiveRenderDuration, |
|
renderCount = item.renderCount; |
|
|
|
return { |
|
'Owner > Component': key, |
|
'Inclusive render time (ms)': roundFloat(inclusiveRenderDuration), |
|
'Instance count': instanceCount, |
|
'Render count': renderCount |
|
}; |
|
}); |
|
consoleTable(table); |
|
} |
|
|
|
function printWasted(flushHistory) { |
|
if (!("development" !== 'production')) { |
|
warnInProduction(); |
|
return; |
|
} |
|
|
|
var stats = getWasted(flushHistory); |
|
var table = stats.map(function (item) { |
|
var key = item.key, |
|
instanceCount = item.instanceCount, |
|
inclusiveRenderDuration = item.inclusiveRenderDuration, |
|
renderCount = item.renderCount; |
|
|
|
return { |
|
'Owner > Component': key, |
|
'Inclusive wasted time (ms)': roundFloat(inclusiveRenderDuration), |
|
'Instance count': instanceCount, |
|
'Render count': renderCount |
|
}; |
|
}); |
|
consoleTable(table); |
|
} |
|
|
|
function printOperations(flushHistory) { |
|
if (!("development" !== 'production')) { |
|
warnInProduction(); |
|
return; |
|
} |
|
|
|
var stats = getOperations(flushHistory); |
|
var table = stats.map(function (stat) { |
|
return { |
|
'Owner > Node': stat.key, |
|
'Operation': stat.type, |
|
'Payload': typeof stat.payload === 'object' ? JSON.stringify(stat.payload) : stat.payload, |
|
'Flush index': stat.flushIndex, |
|
'Owner Component ID': stat.ownerID, |
|
'DOM Component ID': stat.instanceID |
|
}; |
|
}); |
|
consoleTable(table); |
|
} |
|
|
|
var warnedAboutPrintDOM = false; |
|
function printDOM(measurements) { |
|
"development" !== 'production' ? warning(warnedAboutPrintDOM, '`ReactPerf.printDOM(...)` is deprecated. Use ' + '`ReactPerf.printOperations(...)` instead.') : void 0; |
|
warnedAboutPrintDOM = true; |
|
return printOperations(measurements); |
|
} |
|
|
|
var warnedAboutGetMeasurementsSummaryMap = false; |
|
function getMeasurementsSummaryMap(measurements) { |
|
"development" !== 'production' ? warning(warnedAboutGetMeasurementsSummaryMap, '`ReactPerf.getMeasurementsSummaryMap(...)` is deprecated. Use ' + '`ReactPerf.getWasted(...)` instead.') : void 0; |
|
warnedAboutGetMeasurementsSummaryMap = true; |
|
return getWasted(measurements); |
|
} |
|
|
|
function start() { |
|
if (!("development" !== 'production')) { |
|
warnInProduction(); |
|
return; |
|
} |
|
|
|
ReactDebugTool.beginProfiling(); |
|
} |
|
|
|
function stop() { |
|
if (!("development" !== 'production')) { |
|
warnInProduction(); |
|
return; |
|
} |
|
|
|
ReactDebugTool.endProfiling(); |
|
} |
|
|
|
function isRunning() { |
|
if (!("development" !== 'production')) { |
|
warnInProduction(); |
|
return false; |
|
} |
|
|
|
return ReactDebugTool.isProfiling(); |
|
} |
|
|
|
var ReactPerfAnalysis = { |
|
getLastMeasurements: getLastMeasurements, |
|
getExclusive: getExclusive, |
|
getInclusive: getInclusive, |
|
getWasted: getWasted, |
|
getOperations: getOperations, |
|
printExclusive: printExclusive, |
|
printInclusive: printInclusive, |
|
printWasted: printWasted, |
|
printOperations: printOperations, |
|
start: start, |
|
stop: stop, |
|
isRunning: isRunning, |
|
// Deprecated: |
|
printDOM: printDOM, |
|
getMeasurementsSummaryMap: getMeasurementsSummaryMap |
|
}; |
|
|
|
module.exports = ReactPerfAnalysis; |
|
},{"157":157,"158":158,"50":50}],72:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var ReactPropTypeLocationNames = {}; |
|
|
|
if ("development" !== 'production') { |
|
ReactPropTypeLocationNames = { |
|
prop: 'prop', |
|
context: 'context', |
|
childContext: 'child context' |
|
}; |
|
} |
|
|
|
module.exports = ReactPropTypeLocationNames; |
|
},{}],73:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED'; |
|
|
|
module.exports = ReactPropTypesSecret; |
|
},{}],74:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _assign = _dereq_(158); |
|
|
|
var CallbackQueue = _dereq_(6); |
|
var PooledClass = _dereq_(25); |
|
var ReactBrowserEventEmitter = _dereq_(26); |
|
var ReactInputSelection = _dereq_(62); |
|
var ReactInstrumentation = _dereq_(64); |
|
var Transaction = _dereq_(100); |
|
var ReactUpdateQueue = _dereq_(81); |
|
|
|
/** |
|
* 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 `ReactBrowserEventEmitter` before |
|
* the reconciliation. |
|
*/ |
|
initialize: function () { |
|
var currentlyEnabled = ReactBrowserEventEmitter.isEnabled(); |
|
ReactBrowserEventEmitter.setEnabled(false); |
|
return currentlyEnabled; |
|
}, |
|
|
|
/** |
|
* @param {boolean} previouslyEnabled Enabled status of |
|
* `ReactBrowserEventEmitter` before the reconciliation occurred. `close` |
|
* restores the previous value. |
|
*/ |
|
close: function (previouslyEnabled) { |
|
ReactBrowserEventEmitter.setEnabled(previouslyEnabled); |
|
} |
|
}; |
|
|
|
/** |
|
* Provides a queue for collecting `componentDidMount` and |
|
* `componentDidUpdate` callbacks during 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(); |
|
} |
|
}; |
|
|
|
/** |
|
* 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 = [SELECTION_RESTORATION, EVENT_SUPPRESSION, ON_DOM_READY_QUEUEING]; |
|
|
|
if ("development" !== 'production') { |
|
TRANSACTION_WRAPPERS.push({ |
|
initialize: ReactInstrumentation.debugTool.onBeginFlush, |
|
close: ReactInstrumentation.debugTool.onEndFlush |
|
}); |
|
} |
|
|
|
/** |
|
* 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(useCreateElement) { |
|
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 |
|
// `ReactDOMTextComponent` checks it in `mountComponent`.` |
|
this.renderToStaticMarkup = false; |
|
this.reactMountReady = CallbackQueue.getPooled(null); |
|
this.useCreateElement = useCreateElement; |
|
} |
|
|
|
var Mixin = { |
|
/** |
|
* @see Transaction |
|
* @abstract |
|
* @final |
|
* @return {array<object>} List of operation wrap procedures. |
|
* TODO: convert to array<TransactionWrapper> |
|
*/ |
|
getTransactionWrappers: function () { |
|
return TRANSACTION_WRAPPERS; |
|
}, |
|
|
|
/** |
|
* @return {object} The queue to collect `onDOMReady` callbacks with. |
|
*/ |
|
getReactMountReady: function () { |
|
return this.reactMountReady; |
|
}, |
|
|
|
/** |
|
* @return {object} The queue to collect React async events. |
|
*/ |
|
getUpdateQueue: function () { |
|
return ReactUpdateQueue; |
|
}, |
|
|
|
/** |
|
* Save current transaction state -- if the return value from this method is |
|
* passed to `rollback`, the transaction will be reset to that state. |
|
*/ |
|
checkpoint: function () { |
|
// reactMountReady is the our only stateful wrapper |
|
return this.reactMountReady.checkpoint(); |
|
}, |
|
|
|
rollback: function (checkpoint) { |
|
this.reactMountReady.rollback(checkpoint); |
|
}, |
|
|
|
/** |
|
* `PooledClass` looks for this, and will invoke this before allowing this |
|
* instance to be reused. |
|
*/ |
|
destructor: function () { |
|
CallbackQueue.release(this.reactMountReady); |
|
this.reactMountReady = null; |
|
} |
|
}; |
|
|
|
_assign(ReactReconcileTransaction.prototype, Transaction, Mixin); |
|
|
|
PooledClass.addPoolingTo(ReactReconcileTransaction); |
|
|
|
module.exports = ReactReconcileTransaction; |
|
},{"100":100,"158":158,"25":25,"26":26,"6":6,"62":62,"64":64,"81":81}],75:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var ReactRef = _dereq_(76); |
|
var ReactInstrumentation = _dereq_(64); |
|
|
|
var warning = _dereq_(157); |
|
|
|
/** |
|
* Helper to call ReactRef.attachRefs with this composite component, split out |
|
* to avoid allocations in the transaction mount-ready queue. |
|
*/ |
|
function attachRefs() { |
|
ReactRef.attachRefs(this, this._currentElement); |
|
} |
|
|
|
var ReactReconciler = { |
|
|
|
/** |
|
* Initializes the component, renders markup, and registers event listeners. |
|
* |
|
* @param {ReactComponent} internalInstance |
|
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction |
|
* @param {?object} the containing host component instance |
|
* @param {?object} info about the host container |
|
* @return {?string} Rendered markup to be inserted into the DOM. |
|
* @final |
|
* @internal |
|
*/ |
|
mountComponent: function (internalInstance, transaction, hostParent, hostContainerInfo, context, parentDebugID // 0 in production and for roots |
|
) { |
|
if ("development" !== 'production') { |
|
if (internalInstance._debugID !== 0) { |
|
ReactInstrumentation.debugTool.onBeforeMountComponent(internalInstance._debugID, internalInstance._currentElement, parentDebugID); |
|
} |
|
} |
|
var markup = internalInstance.mountComponent(transaction, hostParent, hostContainerInfo, context, parentDebugID); |
|
if (internalInstance._currentElement && internalInstance._currentElement.ref != null) { |
|
transaction.getReactMountReady().enqueue(attachRefs, internalInstance); |
|
} |
|
if ("development" !== 'production') { |
|
if (internalInstance._debugID !== 0) { |
|
ReactInstrumentation.debugTool.onMountComponent(internalInstance._debugID); |
|
} |
|
} |
|
return markup; |
|
}, |
|
|
|
/** |
|
* Returns a value that can be passed to |
|
* ReactComponentEnvironment.replaceNodeWithMarkup. |
|
*/ |
|
getHostNode: function (internalInstance) { |
|
return internalInstance.getHostNode(); |
|
}, |
|
|
|
/** |
|
* Releases any resources allocated by `mountComponent`. |
|
* |
|
* @final |
|
* @internal |
|
*/ |
|
unmountComponent: function (internalInstance, safely) { |
|
if ("development" !== 'production') { |
|
if (internalInstance._debugID !== 0) { |
|
ReactInstrumentation.debugTool.onBeforeUnmountComponent(internalInstance._debugID); |
|
} |
|
} |
|
ReactRef.detachRefs(internalInstance, internalInstance._currentElement); |
|
internalInstance.unmountComponent(safely); |
|
if ("development" !== 'production') { |
|
if (internalInstance._debugID !== 0) { |
|
ReactInstrumentation.debugTool.onUnmountComponent(internalInstance._debugID); |
|
} |
|
} |
|
}, |
|
|
|
/** |
|
* Update a component using a new element. |
|
* |
|
* @param {ReactComponent} internalInstance |
|
* @param {ReactElement} nextElement |
|
* @param {ReactReconcileTransaction} transaction |
|
* @param {object} context |
|
* @internal |
|
*/ |
|
receiveComponent: function (internalInstance, nextElement, transaction, context) { |
|
var prevElement = internalInstance._currentElement; |
|
|
|
if (nextElement === prevElement && context === internalInstance._context) { |
|
// Since elements are immutable after the owner is rendered, |
|
// we can do a cheap identity compare here to determine if this is a |
|
// superfluous reconcile. It's possible for state to be mutable but such |
|
// change should trigger an update of the owner which would recreate |
|
// the element. We explicitly check for the existence of an owner since |
|
// it's possible for an element created outside a composite to be |
|
// deeply mutated and reused. |
|
|
|
// TODO: Bailing out early is just a perf optimization right? |
|
// TODO: Removing the return statement should affect correctness? |
|
return; |
|
} |
|
|
|
if ("development" !== 'production') { |
|
if (internalInstance._debugID !== 0) { |
|
ReactInstrumentation.debugTool.onBeforeUpdateComponent(internalInstance._debugID, nextElement); |
|
} |
|
} |
|
|
|
var refsChanged = ReactRef.shouldUpdateRefs(prevElement, nextElement); |
|
|
|
if (refsChanged) { |
|
ReactRef.detachRefs(internalInstance, prevElement); |
|
} |
|
|
|
internalInstance.receiveComponent(nextElement, transaction, context); |
|
|
|
if (refsChanged && internalInstance._currentElement && internalInstance._currentElement.ref != null) { |
|
transaction.getReactMountReady().enqueue(attachRefs, internalInstance); |
|
} |
|
|
|
if ("development" !== 'production') { |
|
if (internalInstance._debugID !== 0) { |
|
ReactInstrumentation.debugTool.onUpdateComponent(internalInstance._debugID); |
|
} |
|
} |
|
}, |
|
|
|
/** |
|
* Flush any dirty changes in a component. |
|
* |
|
* @param {ReactComponent} internalInstance |
|
* @param {ReactReconcileTransaction} transaction |
|
* @internal |
|
*/ |
|
performUpdateIfNecessary: function (internalInstance, transaction, updateBatchNumber) { |
|
if (internalInstance._updateBatchNumber !== updateBatchNumber) { |
|
// The component's enqueued batch number should always be the current |
|
// batch or the following one. |
|
"development" !== 'production' ? warning(internalInstance._updateBatchNumber == null || internalInstance._updateBatchNumber === updateBatchNumber + 1, 'performUpdateIfNecessary: Unexpected batch number (current %s, ' + 'pending %s)', updateBatchNumber, internalInstance._updateBatchNumber) : void 0; |
|
return; |
|
} |
|
if ("development" !== 'production') { |
|
if (internalInstance._debugID !== 0) { |
|
ReactInstrumentation.debugTool.onBeforeUpdateComponent(internalInstance._debugID, internalInstance._currentElement); |
|
} |
|
} |
|
internalInstance.performUpdateIfNecessary(transaction); |
|
if ("development" !== 'production') { |
|
if (internalInstance._debugID !== 0) { |
|
ReactInstrumentation.debugTool.onUpdateComponent(internalInstance._debugID); |
|
} |
|
} |
|
} |
|
|
|
}; |
|
|
|
module.exports = ReactReconciler; |
|
},{"157":157,"64":64,"76":76}],76:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var ReactOwner = _dereq_(70); |
|
|
|
var ReactRef = {}; |
|
|
|
function attachRef(ref, component, owner) { |
|
if (typeof ref === 'function') { |
|
ref(component.getPublicInstance()); |
|
} else { |
|
// Legacy ref |
|
ReactOwner.addComponentAsRefTo(component, ref, owner); |
|
} |
|
} |
|
|
|
function detachRef(ref, component, owner) { |
|
if (typeof ref === 'function') { |
|
ref(null); |
|
} else { |
|
// Legacy ref |
|
ReactOwner.removeComponentAsRefFrom(component, ref, owner); |
|
} |
|
} |
|
|
|
ReactRef.attachRefs = function (instance, element) { |
|
if (element === null || typeof element !== 'object') { |
|
return; |
|
} |
|
var ref = element.ref; |
|
if (ref != null) { |
|
attachRef(ref, instance, element._owner); |
|
} |
|
}; |
|
|
|
ReactRef.shouldUpdateRefs = function (prevElement, nextElement) { |
|
// 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`. We use the element instead |
|
// of the public this.props because the post processing cannot determine |
|
// a ref. The ref conceptually lives on the element. |
|
|
|
// TODO: Should this even be possible? The owner cannot change because |
|
// it's forbidden by shouldUpdateReactComponent. The ref can change |
|
// if you swap the keys of but not the refs. Reconsider where this check |
|
// is made. It probably belongs where the key checking and |
|
// instantiateReactComponent is done. |
|
|
|
var prevRef = null; |
|
var prevOwner = null; |
|
if (prevElement !== null && typeof prevElement === 'object') { |
|
prevRef = prevElement.ref; |
|
prevOwner = prevElement._owner; |
|
} |
|
|
|
var nextRef = null; |
|
var nextOwner = null; |
|
if (nextElement !== null && typeof nextElement === 'object') { |
|
nextRef = nextElement.ref; |
|
nextOwner = nextElement._owner; |
|
} |
|
|
|
return prevRef !== nextRef || |
|
// If owner changes but we have an unchanged function ref, don't update refs |
|
typeof nextRef === 'string' && nextOwner !== prevOwner; |
|
}; |
|
|
|
ReactRef.detachRefs = function (instance, element) { |
|
if (element === null || typeof element !== 'object') { |
|
return; |
|
} |
|
var ref = element.ref; |
|
if (ref != null) { |
|
detachRef(ref, instance, element._owner); |
|
} |
|
}; |
|
|
|
module.exports = ReactRef; |
|
},{"70":70}],77:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2014-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _assign = _dereq_(158); |
|
|
|
var PooledClass = _dereq_(25); |
|
var Transaction = _dereq_(100); |
|
var ReactInstrumentation = _dereq_(64); |
|
var ReactServerUpdateQueue = _dereq_(78); |
|
|
|
/** |
|
* 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 = []; |
|
|
|
if ("development" !== 'production') { |
|
TRANSACTION_WRAPPERS.push({ |
|
initialize: ReactInstrumentation.debugTool.onBeginFlush, |
|
close: ReactInstrumentation.debugTool.onEndFlush |
|
}); |
|
} |
|
|
|
var noopCallbackQueue = { |
|
enqueue: function () {} |
|
}; |
|
|
|
/** |
|
* @class ReactServerRenderingTransaction |
|
* @param {boolean} renderToStaticMarkup |
|
*/ |
|
function ReactServerRenderingTransaction(renderToStaticMarkup) { |
|
this.reinitializeTransaction(); |
|
this.renderToStaticMarkup = renderToStaticMarkup; |
|
this.useCreateElement = false; |
|
this.updateQueue = new ReactServerUpdateQueue(this); |
|
} |
|
|
|
var Mixin = { |
|
/** |
|
* @see Transaction |
|
* @abstract |
|
* @final |
|
* @return {array} Empty list of operation wrap procedures. |
|
*/ |
|
getTransactionWrappers: function () { |
|
return TRANSACTION_WRAPPERS; |
|
}, |
|
|
|
/** |
|
* @return {object} The queue to collect `onDOMReady` callbacks with. |
|
*/ |
|
getReactMountReady: function () { |
|
return noopCallbackQueue; |
|
}, |
|
|
|
/** |
|
* @return {object} The queue to collect React async events. |
|
*/ |
|
getUpdateQueue: function () { |
|
return this.updateQueue; |
|
}, |
|
|
|
/** |
|
* `PooledClass` looks for this, and will invoke this before allowing this |
|
* instance to be reused. |
|
*/ |
|
destructor: function () {}, |
|
|
|
checkpoint: function () {}, |
|
|
|
rollback: function () {} |
|
}; |
|
|
|
_assign(ReactServerRenderingTransaction.prototype, Transaction, Mixin); |
|
|
|
PooledClass.addPoolingTo(ReactServerRenderingTransaction); |
|
|
|
module.exports = ReactServerRenderingTransaction; |
|
},{"100":100,"158":158,"25":25,"64":64,"78":78}],78:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2015-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } |
|
|
|
var ReactUpdateQueue = _dereq_(81); |
|
|
|
var warning = _dereq_(157); |
|
|
|
function warnNoop(publicInstance, callerName) { |
|
if ("development" !== 'production') { |
|
var constructor = publicInstance.constructor; |
|
"development" !== 'production' ? warning(false, '%s(...): Can only update a mounting component. ' + 'This usually means you called %s() outside componentWillMount() on the server. ' + 'This is a no-op. Please check the code for the %s component.', callerName, callerName, constructor && (constructor.displayName || constructor.name) || 'ReactClass') : void 0; |
|
} |
|
} |
|
|
|
/** |
|
* This is the update queue used for server rendering. |
|
* It delegates to ReactUpdateQueue while server rendering is in progress and |
|
* switches to ReactNoopUpdateQueue after the transaction has completed. |
|
* @class ReactServerUpdateQueue |
|
* @param {Transaction} transaction |
|
*/ |
|
|
|
var ReactServerUpdateQueue = function () { |
|
function ReactServerUpdateQueue(transaction) { |
|
_classCallCheck(this, ReactServerUpdateQueue); |
|
|
|
this.transaction = transaction; |
|
} |
|
|
|
/** |
|
* Checks whether or not this composite component is mounted. |
|
* @param {ReactClass} publicInstance The instance we want to test. |
|
* @return {boolean} True if mounted, false otherwise. |
|
* @protected |
|
* @final |
|
*/ |
|
|
|
|
|
ReactServerUpdateQueue.prototype.isMounted = function isMounted(publicInstance) { |
|
return false; |
|
}; |
|
|
|
/** |
|
* Enqueue a callback that will be executed after all the pending updates |
|
* have processed. |
|
* |
|
* @param {ReactClass} publicInstance The instance to use as `this` context. |
|
* @param {?function} callback Called after state is updated. |
|
* @internal |
|
*/ |
|
|
|
|
|
ReactServerUpdateQueue.prototype.enqueueCallback = function enqueueCallback(publicInstance, callback, callerName) { |
|
if (this.transaction.isInTransaction()) { |
|
ReactUpdateQueue.enqueueCallback(publicInstance, callback, callerName); |
|
} |
|
}; |
|
|
|
/** |
|
* 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 `shouldComponentUpdate`, but it will invoke |
|
* `componentWillUpdate` and `componentDidUpdate`. |
|
* |
|
* @param {ReactClass} publicInstance The instance that should rerender. |
|
* @internal |
|
*/ |
|
|
|
|
|
ReactServerUpdateQueue.prototype.enqueueForceUpdate = function enqueueForceUpdate(publicInstance) { |
|
if (this.transaction.isInTransaction()) { |
|
ReactUpdateQueue.enqueueForceUpdate(publicInstance); |
|
} else { |
|
warnNoop(publicInstance, 'forceUpdate'); |
|
} |
|
}; |
|
|
|
/** |
|
* 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 {ReactClass} publicInstance The instance that should rerender. |
|
* @param {object|function} completeState Next state. |
|
* @internal |
|
*/ |
|
|
|
|
|
ReactServerUpdateQueue.prototype.enqueueReplaceState = function enqueueReplaceState(publicInstance, completeState) { |
|
if (this.transaction.isInTransaction()) { |
|
ReactUpdateQueue.enqueueReplaceState(publicInstance, completeState); |
|
} else { |
|
warnNoop(publicInstance, 'replaceState'); |
|
} |
|
}; |
|
|
|
/** |
|
* Sets a subset of the state. This only exists because _pendingState is |
|
* internal. This provides a merging strategy that is not available to deep |
|
* properties which is confusing. TODO: Expose pendingState or don't use it |
|
* during the merge. |
|
* |
|
* @param {ReactClass} publicInstance The instance that should rerender. |
|
* @param {object|function} partialState Next partial state to be merged with state. |
|
* @internal |
|
*/ |
|
|
|
|
|
ReactServerUpdateQueue.prototype.enqueueSetState = function enqueueSetState(publicInstance, partialState) { |
|
if (this.transaction.isInTransaction()) { |
|
ReactUpdateQueue.enqueueSetState(publicInstance, partialState); |
|
} else { |
|
warnNoop(publicInstance, 'setState'); |
|
} |
|
}; |
|
|
|
return ReactServerUpdateQueue; |
|
}(); |
|
|
|
module.exports = ReactServerUpdateQueue; |
|
},{"157":157,"81":81}],79:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125), |
|
_assign = _dereq_(158); |
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } |
|
|
|
var React = _dereq_(134); |
|
var ReactDefaultInjection = _dereq_(52); |
|
var ReactCompositeComponent = _dereq_(30); |
|
var ReactReconciler = _dereq_(75); |
|
var ReactUpdates = _dereq_(82); |
|
|
|
var emptyObject = _dereq_(143); |
|
var getNextDebugID = _dereq_(117); |
|
var invariant = _dereq_(150); |
|
|
|
var NoopInternalComponent = function () { |
|
function NoopInternalComponent(element) { |
|
_classCallCheck(this, NoopInternalComponent); |
|
|
|
this._renderedOutput = element; |
|
this._currentElement = element; |
|
|
|
if ("development" !== 'production') { |
|
this._debugID = getNextDebugID(); |
|
} |
|
} |
|
|
|
NoopInternalComponent.prototype.mountComponent = function mountComponent() {}; |
|
|
|
NoopInternalComponent.prototype.receiveComponent = function receiveComponent(element) { |
|
this._renderedOutput = element; |
|
this._currentElement = element; |
|
}; |
|
|
|
NoopInternalComponent.prototype.unmountComponent = function unmountComponent() {}; |
|
|
|
NoopInternalComponent.prototype.getHostNode = function getHostNode() { |
|
return undefined; |
|
}; |
|
|
|
NoopInternalComponent.prototype.getPublicInstance = function getPublicInstance() { |
|
return null; |
|
}; |
|
|
|
return NoopInternalComponent; |
|
}(); |
|
|
|
var ShallowComponentWrapper = function (element) { |
|
// TODO: Consolidate with instantiateReactComponent |
|
if ("development" !== 'production') { |
|
this._debugID = getNextDebugID(); |
|
} |
|
|
|
this.construct(element); |
|
}; |
|
_assign(ShallowComponentWrapper.prototype, ReactCompositeComponent, { |
|
_constructComponent: ReactCompositeComponent._constructComponentWithoutOwner, |
|
_instantiateReactComponent: function (element) { |
|
return new NoopInternalComponent(element); |
|
}, |
|
_replaceNodeWithMarkup: function () {}, |
|
_renderValidatedComponent: ReactCompositeComponent._renderValidatedComponentWithoutOwnerOrContext |
|
}); |
|
|
|
function _batchedRender(renderer, element, context) { |
|
var transaction = ReactUpdates.ReactReconcileTransaction.getPooled(true); |
|
renderer._render(element, transaction, context); |
|
ReactUpdates.ReactReconcileTransaction.release(transaction); |
|
} |
|
|
|
var ReactShallowRenderer = function () { |
|
function ReactShallowRenderer() { |
|
_classCallCheck(this, ReactShallowRenderer); |
|
|
|
this._instance = null; |
|
} |
|
|
|
ReactShallowRenderer.prototype.getMountedInstance = function getMountedInstance() { |
|
return this._instance ? this._instance._instance : null; |
|
}; |
|
|
|
ReactShallowRenderer.prototype.render = function render(element, context) { |
|
// Ensure we've done the default injections. This might not be true in the |
|
// case of a simple test that only requires React and the TestUtils in |
|
// conjunction with an inline-requires transform. |
|
ReactDefaultInjection.inject(); |
|
|
|
!React.isValidElement(element) ? "development" !== 'production' ? invariant(false, 'ReactShallowRenderer render(): Invalid component element.%s', typeof element === 'function' ? ' Instead of passing a component class, make sure to instantiate ' + 'it by passing it to React.createElement.' : '') : _prodInvariant('12', typeof element === 'function' ? ' Instead of passing a component class, make sure to instantiate ' + 'it by passing it to React.createElement.' : '') : void 0; |
|
!(typeof element.type !== 'string') ? "development" !== 'production' ? invariant(false, 'ReactShallowRenderer render(): Shallow rendering works only with custom components, not primitives (%s). Instead of calling `.render(el)` and inspecting the rendered output, look at `el.props` directly instead.', element.type) : _prodInvariant('13', element.type) : void 0; |
|
|
|
if (!context) { |
|
context = emptyObject; |
|
} |
|
ReactUpdates.batchedUpdates(_batchedRender, this, element, context); |
|
|
|
return this.getRenderOutput(); |
|
}; |
|
|
|
ReactShallowRenderer.prototype.getRenderOutput = function getRenderOutput() { |
|
return this._instance && this._instance._renderedComponent && this._instance._renderedComponent._renderedOutput || null; |
|
}; |
|
|
|
ReactShallowRenderer.prototype.unmount = function unmount() { |
|
if (this._instance) { |
|
ReactReconciler.unmountComponent(this._instance, false); |
|
} |
|
}; |
|
|
|
ReactShallowRenderer.prototype._render = function _render(element, transaction, context) { |
|
if (this._instance) { |
|
ReactReconciler.receiveComponent(this._instance, element, transaction, context); |
|
} else { |
|
var instance = new ShallowComponentWrapper(element); |
|
ReactReconciler.mountComponent(instance, transaction, null, null, context, 0); |
|
this._instance = instance; |
|
} |
|
}; |
|
|
|
return ReactShallowRenderer; |
|
}(); |
|
|
|
module.exports = ReactShallowRenderer; |
|
},{"117":117,"125":125,"134":134,"143":143,"150":150,"158":158,"30":30,"52":52,"75":75,"82":82}],80:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125), |
|
_assign = _dereq_(158); |
|
|
|
var EventConstants = _dereq_(16); |
|
var EventPluginHub = _dereq_(17); |
|
var EventPluginRegistry = _dereq_(18); |
|
var EventPropagators = _dereq_(20); |
|
var React = _dereq_(134); |
|
var ReactDOM = _dereq_(31); |
|
var ReactDOMComponentTree = _dereq_(34); |
|
var ReactBrowserEventEmitter = _dereq_(26); |
|
var ReactInstanceMap = _dereq_(63); |
|
var ReactUpdates = _dereq_(82); |
|
var SyntheticEvent = _dereq_(91); |
|
var ReactShallowRenderer = _dereq_(79); |
|
|
|
var findDOMNode = _dereq_(108); |
|
var invariant = _dereq_(150); |
|
|
|
var topLevelTypes = EventConstants.topLevelTypes; |
|
|
|
function Event(suffix) {} |
|
|
|
/** |
|
* @class ReactTestUtils |
|
*/ |
|
|
|
function findAllInRenderedTreeInternal(inst, test) { |
|
if (!inst || !inst.getPublicInstance) { |
|
return []; |
|
} |
|
var publicInst = inst.getPublicInstance(); |
|
var ret = test(publicInst) ? [publicInst] : []; |
|
var currentElement = inst._currentElement; |
|
if (ReactTestUtils.isDOMComponent(publicInst)) { |
|
var renderedChildren = inst._renderedChildren; |
|
var key; |
|
for (key in renderedChildren) { |
|
if (!renderedChildren.hasOwnProperty(key)) { |
|
continue; |
|
} |
|
ret = ret.concat(findAllInRenderedTreeInternal(renderedChildren[key], test)); |
|
} |
|
} else if (React.isValidElement(currentElement) && typeof currentElement.type === 'function') { |
|
ret = ret.concat(findAllInRenderedTreeInternal(inst._renderedComponent, test)); |
|
} |
|
return ret; |
|
} |
|
|
|
/** |
|
* Utilities for making it easy to test React components. |
|
* |
|
* See https://facebook.github.io/react/docs/test-utils.html |
|
* |
|
* Todo: Support the entire DOM.scry query syntax. For now, these simple |
|
* utilities will suffice for testing purposes. |
|
* @lends ReactTestUtils |
|
*/ |
|
var ReactTestUtils = { |
|
renderIntoDocument: function (element) { |
|
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 ReactDOM.render(element, div); |
|
}, |
|
|
|
isElement: function (element) { |
|
return React.isValidElement(element); |
|
}, |
|
|
|
isElementOfType: function (inst, convenienceConstructor) { |
|
return React.isValidElement(inst) && inst.type === convenienceConstructor; |
|
}, |
|
|
|
isDOMComponent: function (inst) { |
|
return !!(inst && inst.nodeType === 1 && inst.tagName); |
|
}, |
|
|
|
isDOMComponentElement: function (inst) { |
|
return !!(inst && React.isValidElement(inst) && !!inst.tagName); |
|
}, |
|
|
|
isCompositeComponent: function (inst) { |
|
if (ReactTestUtils.isDOMComponent(inst)) { |
|
// Accessing inst.setState warns; just return false as that'll be what |
|
// this returns when we have DOM nodes as refs directly |
|
return false; |
|
} |
|
return inst != null && typeof inst.render === 'function' && typeof inst.setState === 'function'; |
|
}, |
|
|
|
isCompositeComponentWithType: function (inst, type) { |
|
if (!ReactTestUtils.isCompositeComponent(inst)) { |
|
return false; |
|
} |
|
var internalInstance = ReactInstanceMap.get(inst); |
|
var constructor = internalInstance._currentElement.type; |
|
|
|
return constructor === type; |
|
}, |
|
|
|
isCompositeComponentElement: function (inst) { |
|
if (!React.isValidElement(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'; |
|
}, |
|
|
|
isCompositeComponentElementWithType: function (inst, type) { |
|
var internalInstance = ReactInstanceMap.get(inst); |
|
var constructor = internalInstance._currentElement.type; |
|
|
|
return !!(ReactTestUtils.isCompositeComponentElement(inst) && constructor === type); |
|
}, |
|
|
|
getRenderedChildOfCompositeComponent: function (inst) { |
|
if (!ReactTestUtils.isCompositeComponent(inst)) { |
|
return null; |
|
} |
|
var internalInstance = ReactInstanceMap.get(inst); |
|
return internalInstance._renderedComponent.getPublicInstance(); |
|
}, |
|
|
|
findAllInRenderedTree: function (inst, test) { |
|
if (!inst) { |
|
return []; |
|
} |
|
!ReactTestUtils.isCompositeComponent(inst) ? "development" !== 'production' ? invariant(false, 'findAllInRenderedTree(...): instance must be a composite component') : _prodInvariant('10') : void 0; |
|
return findAllInRenderedTreeInternal(ReactInstanceMap.get(inst), test); |
|
}, |
|
|
|
/** |
|
* Finds all instance of components in the rendered tree that are DOM |
|
* components with the class name matching `className`. |
|
* @return {array} an array of all the matches. |
|
*/ |
|
scryRenderedDOMComponentsWithClass: function (root, classNames) { |
|
return ReactTestUtils.findAllInRenderedTree(root, function (inst) { |
|
if (ReactTestUtils.isDOMComponent(inst)) { |
|
var className = inst.className; |
|
if (typeof className !== 'string') { |
|
// SVG, probably. |
|
className = inst.getAttribute('class') || ''; |
|
} |
|
var classList = className.split(/\s+/); |
|
|
|
if (!Array.isArray(classNames)) { |
|
!(classNames !== undefined) ? "development" !== 'production' ? invariant(false, 'TestUtils.scryRenderedDOMComponentsWithClass expects a className as a second argument.') : _prodInvariant('11') : void 0; |
|
classNames = classNames.split(/\s+/); |
|
} |
|
return classNames.every(function (name) { |
|
return classList.indexOf(name) !== -1; |
|
}); |
|
} |
|
return false; |
|
}); |
|
}, |
|
|
|
/** |
|
* 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 (found: ' + all.length + ') ' + '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 {array} an array of all the matches. |
|
*/ |
|
scryRenderedDOMComponentsWithTag: function (root, tagName) { |
|
return ReactTestUtils.findAllInRenderedTree(root, function (inst) { |
|
return ReactTestUtils.isDOMComponent(inst) && inst.tagName.toUpperCase() === 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 (found: ' + all.length + ') ' + 'for tag:' + tagName); |
|
} |
|
return all[0]; |
|
}, |
|
|
|
/** |
|
* Finds all instances of components with type equal to `componentType`. |
|
* @return {array} 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 (found: ' + all.length + ') ' + '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) { |
|
mockTagName = mockTagName || module.mockTagName || 'div'; |
|
|
|
module.prototype.render.mockImplementation(function () { |
|
return React.createElement(mockTagName, null, this.props.children); |
|
}); |
|
|
|
return this; |
|
}, |
|
|
|
/** |
|
* Simulates a top level event being dispatched from a raw event that occurred |
|
* on an `Element` node. |
|
* @param {Object} topLevelType 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) { |
|
fakeNativeEvent.target = node; |
|
ReactBrowserEventEmitter.ReactEventListener.dispatchEvent(topLevelType, fakeNativeEvent); |
|
}, |
|
|
|
/** |
|
* Simulates a top level event being dispatched from a raw event that occurred |
|
* on the `ReactDOMComponent` `comp`. |
|
* @param {Object} topLevelType A type from `EventConstants.topLevelTypes`. |
|
* @param {!ReactDOMComponent} comp |
|
* @param {?Event} fakeNativeEvent Fake native event to use in SyntheticEvent. |
|
*/ |
|
simulateNativeEventOnDOMComponent: function (topLevelType, comp, fakeNativeEvent) { |
|
ReactTestUtils.simulateNativeEventOnNode(topLevelType, findDOMNode(comp), fakeNativeEvent); |
|
}, |
|
|
|
nativeTouchData: function (x, y) { |
|
return { |
|
touches: [{ pageX: x, pageY: y }] |
|
}; |
|
}, |
|
|
|
createRenderer: function () { |
|
return new ReactShallowRenderer(); |
|
}, |
|
|
|
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; |
|
!!React.isValidElement(domComponentOrNode) ? "development" !== 'production' ? invariant(false, 'TestUtils.Simulate expects a component instance and not a ReactElement.TestUtils.Simulate will not work if you are using shallow rendering.') : _prodInvariant('14') : void 0; |
|
if (ReactTestUtils.isDOMComponent(domComponentOrNode)) { |
|
node = findDOMNode(domComponentOrNode); |
|
} else if (domComponentOrNode.tagName) { |
|
node = domComponentOrNode; |
|
} |
|
|
|
var dispatchConfig = EventPluginRegistry.eventNameDispatchConfigs[eventType]; |
|
|
|
var fakeNativeEvent = new Event(); |
|
fakeNativeEvent.target = node; |
|
fakeNativeEvent.type = eventType.toLowerCase(); |
|
|
|
// 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(dispatchConfig, ReactDOMComponentTree.getInstanceFromNode(node), fakeNativeEvent, node); |
|
// Since we aren't using pooling, always persist the event. This will make |
|
// sure it's marked and won't warn when setting additional properties. |
|
event.persist(); |
|
_assign(event, eventData); |
|
|
|
if (dispatchConfig.phasedRegistrationNames) { |
|
EventPropagators.accumulateTwoPhaseDispatches(event); |
|
} else { |
|
EventPropagators.accumulateDirectDispatches(event); |
|
} |
|
|
|
ReactUpdates.batchedUpdates(function () { |
|
EventPluginHub.enqueueEvents(event); |
|
EventPluginHub.processEventQueue(true); |
|
}); |
|
}; |
|
} |
|
|
|
function buildSimulators() { |
|
ReactTestUtils.Simulate = {}; |
|
|
|
var eventType; |
|
for (eventType in EventPluginRegistry.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); |
|
_assign(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); |
|
} |
|
}; |
|
} |
|
|
|
Object.keys(topLevelTypes).forEach(function (eventType) { |
|
// 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; |
|
},{"108":108,"125":125,"134":134,"150":150,"158":158,"16":16,"17":17,"18":18,"20":20,"26":26,"31":31,"34":34,"63":63,"79":79,"82":82,"91":91}],81:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2015-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125); |
|
|
|
var ReactCurrentOwner = _dereq_(133); |
|
var ReactInstanceMap = _dereq_(63); |
|
var ReactInstrumentation = _dereq_(64); |
|
var ReactUpdates = _dereq_(82); |
|
|
|
var invariant = _dereq_(150); |
|
var warning = _dereq_(157); |
|
|
|
function enqueueUpdate(internalInstance) { |
|
ReactUpdates.enqueueUpdate(internalInstance); |
|
} |
|
|
|
function formatUnexpectedArgument(arg) { |
|
var type = typeof arg; |
|
if (type !== 'object') { |
|
return type; |
|
} |
|
var displayName = arg.constructor && arg.constructor.name || type; |
|
var keys = Object.keys(arg); |
|
if (keys.length > 0 && keys.length < 20) { |
|
return displayName + ' (keys: ' + keys.join(', ') + ')'; |
|
} |
|
return displayName; |
|
} |
|
|
|
function getInternalInstanceReadyForUpdate(publicInstance, callerName) { |
|
var internalInstance = ReactInstanceMap.get(publicInstance); |
|
if (!internalInstance) { |
|
if ("development" !== 'production') { |
|
var ctor = publicInstance.constructor; |
|
// Only warn when we have a callerName. Otherwise we should be silent. |
|
// We're probably calling from enqueueCallback. We don't want to warn |
|
// there because we already warned for the corresponding lifecycle method. |
|
"development" !== 'production' ? warning(!callerName, '%s(...): Can only update a mounted or mounting component. ' + 'This usually means you called %s() on an unmounted component. ' + 'This is a no-op. Please check the code for the %s component.', callerName, callerName, ctor && (ctor.displayName || ctor.name) || 'ReactClass') : void 0; |
|
} |
|
return null; |
|
} |
|
|
|
if ("development" !== 'production') { |
|
"development" !== 'production' ? warning(ReactCurrentOwner.current == null, '%s(...): Cannot update during an existing state transition (such as ' + 'within `render` or another component\'s constructor). Render methods ' + 'should be a pure function of props and state; constructor ' + 'side-effects are an anti-pattern, but can be moved to ' + '`componentWillMount`.', callerName) : void 0; |
|
} |
|
|
|
return internalInstance; |
|
} |
|
|
|
/** |
|
* ReactUpdateQueue allows for state updates to be scheduled into a later |
|
* reconciliation step. |
|
*/ |
|
var ReactUpdateQueue = { |
|
|
|
/** |
|
* Checks whether or not this composite component is mounted. |
|
* @param {ReactClass} publicInstance The instance we want to test. |
|
* @return {boolean} True if mounted, false otherwise. |
|
* @protected |
|
* @final |
|
*/ |
|
isMounted: function (publicInstance) { |
|
if ("development" !== 'production') { |
|
var owner = ReactCurrentOwner.current; |
|
if (owner !== null) { |
|
"development" !== 'production' ? warning(owner._warnedAboutRefsInRender, '%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', owner.getName() || 'A component') : void 0; |
|
owner._warnedAboutRefsInRender = true; |
|
} |
|
} |
|
var internalInstance = ReactInstanceMap.get(publicInstance); |
|
if (internalInstance) { |
|
// During componentWillMount and render this will still be null but after |
|
// that will always render to something. At least for now. So we can use |
|
// this hack. |
|
return !!internalInstance._renderedComponent; |
|
} else { |
|
return false; |
|
} |
|
}, |
|
|
|
/** |
|
* Enqueue a callback that will be executed after all the pending updates |
|
* have processed. |
|
* |
|
* @param {ReactClass} publicInstance The instance to use as `this` context. |
|
* @param {?function} callback Called after state is updated. |
|
* @param {string} callerName Name of the calling function in the public API. |
|
* @internal |
|
*/ |
|
enqueueCallback: function (publicInstance, callback, callerName) { |
|
ReactUpdateQueue.validateCallback(callback, callerName); |
|
var internalInstance = getInternalInstanceReadyForUpdate(publicInstance); |
|
|
|
// Previously we would throw an error if we didn't have an internal |
|
// instance. Since we want to make it a no-op instead, we mirror the same |
|
// behavior we have in other enqueue* methods. |
|
// We also need to ignore callbacks in componentWillMount. See |
|
// enqueueUpdates. |
|
if (!internalInstance) { |
|
return null; |
|
} |
|
|
|
if (internalInstance._pendingCallbacks) { |
|
internalInstance._pendingCallbacks.push(callback); |
|
} else { |
|
internalInstance._pendingCallbacks = [callback]; |
|
} |
|
// TODO: The callback here is ignored when setState is called from |
|
// componentWillMount. Either fix it or disallow doing so completely in |
|
// favor of getInitialState. Alternatively, we can disallow |
|
// componentWillMount during server-side rendering. |
|
enqueueUpdate(internalInstance); |
|
}, |
|
|
|
enqueueCallbackInternal: function (internalInstance, callback) { |
|
if (internalInstance._pendingCallbacks) { |
|
internalInstance._pendingCallbacks.push(callback); |
|
} else { |
|
internalInstance._pendingCallbacks = [callback]; |
|
} |
|
enqueueUpdate(internalInstance); |
|
}, |
|
|
|
/** |
|
* 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 `shouldComponentUpdate`, but it will invoke |
|
* `componentWillUpdate` and `componentDidUpdate`. |
|
* |
|
* @param {ReactClass} publicInstance The instance that should rerender. |
|
* @internal |
|
*/ |
|
enqueueForceUpdate: function (publicInstance) { |
|
var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'forceUpdate'); |
|
|
|
if (!internalInstance) { |
|
return; |
|
} |
|
|
|
internalInstance._pendingForceUpdate = true; |
|
|
|
enqueueUpdate(internalInstance); |
|
}, |
|
|
|
/** |
|
* 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 {ReactClass} publicInstance The instance that should rerender. |
|
* @param {object} completeState Next state. |
|
* @internal |
|
*/ |
|
enqueueReplaceState: function (publicInstance, completeState) { |
|
var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'replaceState'); |
|
|
|
if (!internalInstance) { |
|
return; |
|
} |
|
|
|
internalInstance._pendingStateQueue = [completeState]; |
|
internalInstance._pendingReplaceState = true; |
|
|
|
enqueueUpdate(internalInstance); |
|
}, |
|
|
|
/** |
|
* Sets a subset of the state. This only exists because _pendingState is |
|
* internal. This provides a merging strategy that is not available to deep |
|
* properties which is confusing. TODO: Expose pendingState or don't use it |
|
* during the merge. |
|
* |
|
* @param {ReactClass} publicInstance The instance that should rerender. |
|
* @param {object} partialState Next partial state to be merged with state. |
|
* @internal |
|
*/ |
|
enqueueSetState: function (publicInstance, partialState) { |
|
if ("development" !== 'production') { |
|
ReactInstrumentation.debugTool.onSetState(); |
|
"development" !== 'production' ? warning(partialState != null, 'setState(...): You passed an undefined or null state object; ' + 'instead, use forceUpdate().') : void 0; |
|
} |
|
|
|
var internalInstance = getInternalInstanceReadyForUpdate(publicInstance, 'setState'); |
|
|
|
if (!internalInstance) { |
|
return; |
|
} |
|
|
|
var queue = internalInstance._pendingStateQueue || (internalInstance._pendingStateQueue = []); |
|
queue.push(partialState); |
|
|
|
enqueueUpdate(internalInstance); |
|
}, |
|
|
|
enqueueElementInternal: function (internalInstance, nextElement, nextContext) { |
|
internalInstance._pendingElement = nextElement; |
|
// TODO: introduce _pendingContext instead of setting it directly. |
|
internalInstance._context = nextContext; |
|
enqueueUpdate(internalInstance); |
|
}, |
|
|
|
validateCallback: function (callback, callerName) { |
|
!(!callback || typeof callback === 'function') ? "development" !== 'production' ? invariant(false, '%s(...): Expected the last optional `callback` argument to be a function. Instead received: %s.', callerName, formatUnexpectedArgument(callback)) : _prodInvariant('122', callerName, formatUnexpectedArgument(callback)) : void 0; |
|
} |
|
|
|
}; |
|
|
|
module.exports = ReactUpdateQueue; |
|
},{"125":125,"133":133,"150":150,"157":157,"63":63,"64":64,"82":82}],82:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125), |
|
_assign = _dereq_(158); |
|
|
|
var CallbackQueue = _dereq_(6); |
|
var PooledClass = _dereq_(25); |
|
var ReactFeatureFlags = _dereq_(58); |
|
var ReactReconciler = _dereq_(75); |
|
var Transaction = _dereq_(100); |
|
|
|
var invariant = _dereq_(150); |
|
|
|
var dirtyComponents = []; |
|
var updateBatchNumber = 0; |
|
var asapCallbackQueue = CallbackQueue.getPooled(); |
|
var asapEnqueued = false; |
|
|
|
var batchingStrategy = null; |
|
|
|
function ensureInjected() { |
|
!(ReactUpdates.ReactReconcileTransaction && batchingStrategy) ? "development" !== 'production' ? invariant(false, 'ReactUpdates: must inject a reconcile transaction class and batching strategy') : _prodInvariant('123') : void 0; |
|
} |
|
|
|
var NESTED_UPDATES = { |
|
initialize: function () { |
|
this.dirtyComponentsLength = dirtyComponents.length; |
|
}, |
|
close: function () { |
|
if (this.dirtyComponentsLength !== dirtyComponents.length) { |
|
// Additional updates were enqueued by componentDidUpdate handlers or |
|
// similar; before our own UPDATE_QUEUEING wrapper closes, we want to run |
|
// these new updates so that if A's componentDidUpdate calls setState on |
|
// B, B will update before the callback A's updater provided when calling |
|
// setState. |
|
dirtyComponents.splice(0, this.dirtyComponentsLength); |
|
flushBatchedUpdates(); |
|
} else { |
|
dirtyComponents.length = 0; |
|
} |
|
} |
|
}; |
|
|
|
var UPDATE_QUEUEING = { |
|
initialize: function () { |
|
this.callbackQueue.reset(); |
|
}, |
|
close: function () { |
|
this.callbackQueue.notifyAll(); |
|
} |
|
}; |
|
|
|
var TRANSACTION_WRAPPERS = [NESTED_UPDATES, UPDATE_QUEUEING]; |
|
|
|
function ReactUpdatesFlushTransaction() { |
|
this.reinitializeTransaction(); |
|
this.dirtyComponentsLength = null; |
|
this.callbackQueue = CallbackQueue.getPooled(); |
|
this.reconcileTransaction = ReactUpdates.ReactReconcileTransaction.getPooled( |
|
/* useCreateElement */true); |
|
} |
|
|
|
_assign(ReactUpdatesFlushTransaction.prototype, Transaction, { |
|
getTransactionWrappers: function () { |
|
return TRANSACTION_WRAPPERS; |
|
}, |
|
|
|
destructor: function () { |
|
this.dirtyComponentsLength = null; |
|
CallbackQueue.release(this.callbackQueue); |
|
this.callbackQueue = null; |
|
ReactUpdates.ReactReconcileTransaction.release(this.reconcileTransaction); |
|
this.reconcileTransaction = null; |
|
}, |
|
|
|
perform: function (method, scope, a) { |
|
// Essentially calls `this.reconcileTransaction.perform(method, scope, a)` |
|
// with this transaction's wrappers around it. |
|
return Transaction.perform.call(this, this.reconcileTransaction.perform, this.reconcileTransaction, method, scope, a); |
|
} |
|
}); |
|
|
|
PooledClass.addPoolingTo(ReactUpdatesFlushTransaction); |
|
|
|
function batchedUpdates(callback, a, b, c, d, e) { |
|
ensureInjected(); |
|
return batchingStrategy.batchedUpdates(callback, a, b, c, d, e); |
|
} |
|
|
|
/** |
|
* Array comparator for ReactComponents by mount ordering. |
|
* |
|
* @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 mountOrderComparator(c1, c2) { |
|
return c1._mountOrder - c2._mountOrder; |
|
} |
|
|
|
function runBatchedUpdates(transaction) { |
|
var len = transaction.dirtyComponentsLength; |
|
!(len === dirtyComponents.length) ? "development" !== 'production' ? invariant(false, 'Expected flush transaction\'s stored dirty-components length (%s) to match dirty-components array length (%s).', len, dirtyComponents.length) : _prodInvariant('124', len, dirtyComponents.length) : void 0; |
|
|
|
// 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(mountOrderComparator); |
|
|
|
// Any updates enqueued while reconciling must be performed after this entire |
|
// batch. Otherwise, if dirtyComponents is [A, B] where A has children B and |
|
// C, B could update twice in a single batch if C's render enqueues an update |
|
// to B (since B would have already updated, we should skip it, and the only |
|
// way we can know to do so is by checking the batch counter). |
|
updateBatchNumber++; |
|
|
|
for (var i = 0; i < len; i++) { |
|
// If a component is unmounted before pending changes apply, it will still |
|
// be here, but we assume that it has cleared its _pendingCallbacks and |
|
// that performUpdateIfNecessary is a noop. |
|
var component = dirtyComponents[i]; |
|
|
|
// 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; |
|
|
|
var markerName; |
|
if (ReactFeatureFlags.logTopLevelRenders) { |
|
var namedComponent = component; |
|
// Duck type TopLevelWrapper. This is probably always true. |
|
if (component._currentElement.type.isReactTopLevelWrapper) { |
|
namedComponent = component._renderedComponent; |
|
} |
|
markerName = 'React update: ' + namedComponent.getName(); |
|
console.time(markerName); |
|
} |
|
|
|
ReactReconciler.performUpdateIfNecessary(component, transaction.reconcileTransaction, updateBatchNumber); |
|
|
|
if (markerName) { |
|
console.timeEnd(markerName); |
|
} |
|
|
|
if (callbacks) { |
|
for (var j = 0; j < callbacks.length; j++) { |
|
transaction.callbackQueue.enqueue(callbacks[j], component.getPublicInstance()); |
|
} |
|
} |
|
} |
|
} |
|
|
|
var flushBatchedUpdates = function () { |
|
// ReactUpdatesFlushTransaction's wrappers will clear the dirtyComponents |
|
// array and perform any updates enqueued by mount-ready handlers (i.e., |
|
// componentDidUpdate) but we need to check here too in order to catch |
|
// updates enqueued by setState callbacks and asap calls. |
|
while (dirtyComponents.length || asapEnqueued) { |
|
if (dirtyComponents.length) { |
|
var transaction = ReactUpdatesFlushTransaction.getPooled(); |
|
transaction.perform(runBatchedUpdates, null, transaction); |
|
ReactUpdatesFlushTransaction.release(transaction); |
|
} |
|
|
|
if (asapEnqueued) { |
|
asapEnqueued = false; |
|
var queue = asapCallbackQueue; |
|
asapCallbackQueue = CallbackQueue.getPooled(); |
|
queue.notifyAll(); |
|
CallbackQueue.release(queue); |
|
} |
|
} |
|
}; |
|
|
|
/** |
|
* 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) { |
|
ensureInjected(); |
|
|
|
// Various parts of our code (such as ReactCompositeComponent's |
|
// _renderValidatedComponent) assume that calls to render aren't nested; |
|
// verify that that's the case. (This is called by each top-level update |
|
// function, like setState, forceUpdate, etc.; creation and |
|
// destruction of top-level components is guarded in ReactMount.) |
|
|
|
if (!batchingStrategy.isBatchingUpdates) { |
|
batchingStrategy.batchedUpdates(enqueueUpdate, component); |
|
return; |
|
} |
|
|
|
dirtyComponents.push(component); |
|
if (component._updateBatchNumber == null) { |
|
component._updateBatchNumber = updateBatchNumber + 1; |
|
} |
|
} |
|
|
|
/** |
|
* Enqueue a callback to be run at the end of the current batching cycle. Throws |
|
* if no updates are currently being performed. |
|
*/ |
|
function asap(callback, context) { |
|
!batchingStrategy.isBatchingUpdates ? "development" !== 'production' ? invariant(false, 'ReactUpdates.asap: Can\'t enqueue an asap callback in a context whereupdates are not being batched.') : _prodInvariant('125') : void 0; |
|
asapCallbackQueue.enqueue(callback, context); |
|
asapEnqueued = true; |
|
} |
|
|
|
var ReactUpdatesInjection = { |
|
injectReconcileTransaction: function (ReconcileTransaction) { |
|
!ReconcileTransaction ? "development" !== 'production' ? invariant(false, 'ReactUpdates: must provide a reconcile transaction class') : _prodInvariant('126') : void 0; |
|
ReactUpdates.ReactReconcileTransaction = ReconcileTransaction; |
|
}, |
|
|
|
injectBatchingStrategy: function (_batchingStrategy) { |
|
!_batchingStrategy ? "development" !== 'production' ? invariant(false, 'ReactUpdates: must provide a batching strategy') : _prodInvariant('127') : void 0; |
|
!(typeof _batchingStrategy.batchedUpdates === 'function') ? "development" !== 'production' ? invariant(false, 'ReactUpdates: must provide a batchedUpdates() function') : _prodInvariant('128') : void 0; |
|
!(typeof _batchingStrategy.isBatchingUpdates === 'boolean') ? "development" !== 'production' ? invariant(false, 'ReactUpdates: must provide an isBatchingUpdates boolean attribute') : _prodInvariant('129') : void 0; |
|
batchingStrategy = _batchingStrategy; |
|
} |
|
}; |
|
|
|
var ReactUpdates = { |
|
/** |
|
* React references `ReactReconcileTransaction` using this property in order |
|
* to allow dependency injection. |
|
* |
|
* @internal |
|
*/ |
|
ReactReconcileTransaction: null, |
|
|
|
batchedUpdates: batchedUpdates, |
|
enqueueUpdate: enqueueUpdate, |
|
flushBatchedUpdates: flushBatchedUpdates, |
|
injection: ReactUpdatesInjection, |
|
asap: asap |
|
}; |
|
|
|
module.exports = ReactUpdates; |
|
},{"100":100,"125":125,"150":150,"158":158,"25":25,"58":58,"6":6,"75":75}],83:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
module.exports = '15.4.2'; |
|
},{}],84:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var NS = { |
|
xlink: 'http://www.w3.org/1999/xlink', |
|
xml: 'http://www.w3.org/XML/1998/namespace' |
|
}; |
|
|
|
// We use attributes for everything SVG so let's avoid some duplication and run |
|
// code instead. |
|
// The following are all specified in the HTML config already so we exclude here. |
|
// - class (as className) |
|
// - color |
|
// - height |
|
// - id |
|
// - lang |
|
// - max |
|
// - media |
|
// - method |
|
// - min |
|
// - name |
|
// - style |
|
// - target |
|
// - type |
|
// - width |
|
var ATTRS = { |
|
accentHeight: 'accent-height', |
|
accumulate: 0, |
|
additive: 0, |
|
alignmentBaseline: 'alignment-baseline', |
|
allowReorder: 'allowReorder', |
|
alphabetic: 0, |
|
amplitude: 0, |
|
arabicForm: 'arabic-form', |
|
ascent: 0, |
|
attributeName: 'attributeName', |
|
attributeType: 'attributeType', |
|
autoReverse: 'autoReverse', |
|
azimuth: 0, |
|
baseFrequency: 'baseFrequency', |
|
baseProfile: 'baseProfile', |
|
baselineShift: 'baseline-shift', |
|
bbox: 0, |
|
begin: 0, |
|
bias: 0, |
|
by: 0, |
|
calcMode: 'calcMode', |
|
capHeight: 'cap-height', |
|
clip: 0, |
|
clipPath: 'clip-path', |
|
clipRule: 'clip-rule', |
|
clipPathUnits: 'clipPathUnits', |
|
colorInterpolation: 'color-interpolation', |
|
colorInterpolationFilters: 'color-interpolation-filters', |
|
colorProfile: 'color-profile', |
|
colorRendering: 'color-rendering', |
|
contentScriptType: 'contentScriptType', |
|
contentStyleType: 'contentStyleType', |
|
cursor: 0, |
|
cx: 0, |
|
cy: 0, |
|
d: 0, |
|
decelerate: 0, |
|
descent: 0, |
|
diffuseConstant: 'diffuseConstant', |
|
direction: 0, |
|
display: 0, |
|
divisor: 0, |
|
dominantBaseline: 'dominant-baseline', |
|
dur: 0, |
|
dx: 0, |
|
dy: 0, |
|
edgeMode: 'edgeMode', |
|
elevation: 0, |
|
enableBackground: 'enable-background', |
|
end: 0, |
|
exponent: 0, |
|
externalResourcesRequired: 'externalResourcesRequired', |
|
fill: 0, |
|
fillOpacity: 'fill-opacity', |
|
fillRule: 'fill-rule', |
|
filter: 0, |
|
filterRes: 'filterRes', |
|
filterUnits: 'filterUnits', |
|
floodColor: 'flood-color', |
|
floodOpacity: 'flood-opacity', |
|
focusable: 0, |
|
fontFamily: 'font-family', |
|
fontSize: 'font-size', |
|
fontSizeAdjust: 'font-size-adjust', |
|
fontStretch: 'font-stretch', |
|
fontStyle: 'font-style', |
|
fontVariant: 'font-variant', |
|
fontWeight: 'font-weight', |
|
format: 0, |
|
from: 0, |
|
fx: 0, |
|
fy: 0, |
|
g1: 0, |
|
g2: 0, |
|
glyphName: 'glyph-name', |
|
glyphOrientationHorizontal: 'glyph-orientation-horizontal', |
|
glyphOrientationVertical: 'glyph-orientation-vertical', |
|
glyphRef: 'glyphRef', |
|
gradientTransform: 'gradientTransform', |
|
gradientUnits: 'gradientUnits', |
|
hanging: 0, |
|
horizAdvX: 'horiz-adv-x', |
|
horizOriginX: 'horiz-origin-x', |
|
ideographic: 0, |
|
imageRendering: 'image-rendering', |
|
'in': 0, |
|
in2: 0, |
|
intercept: 0, |
|
k: 0, |
|
k1: 0, |
|
k2: 0, |
|
k3: 0, |
|
k4: 0, |
|
kernelMatrix: 'kernelMatrix', |
|
kernelUnitLength: 'kernelUnitLength', |
|
kerning: 0, |
|
keyPoints: 'keyPoints', |
|
keySplines: 'keySplines', |
|
keyTimes: 'keyTimes', |
|
lengthAdjust: 'lengthAdjust', |
|
letterSpacing: 'letter-spacing', |
|
lightingColor: 'lighting-color', |
|
limitingConeAngle: 'limitingConeAngle', |
|
local: 0, |
|
markerEnd: 'marker-end', |
|
markerMid: 'marker-mid', |
|
markerStart: 'marker-start', |
|
markerHeight: 'markerHeight', |
|
markerUnits: 'markerUnits', |
|
markerWidth: 'markerWidth', |
|
mask: 0, |
|
maskContentUnits: 'maskContentUnits', |
|
maskUnits: 'maskUnits', |
|
mathematical: 0, |
|
mode: 0, |
|
numOctaves: 'numOctaves', |
|
offset: 0, |
|
opacity: 0, |
|
operator: 0, |
|
order: 0, |
|
orient: 0, |
|
orientation: 0, |
|
origin: 0, |
|
overflow: 0, |
|
overlinePosition: 'overline-position', |
|
overlineThickness: 'overline-thickness', |
|
paintOrder: 'paint-order', |
|
panose1: 'panose-1', |
|
pathLength: 'pathLength', |
|
patternContentUnits: 'patternContentUnits', |
|
patternTransform: 'patternTransform', |
|
patternUnits: 'patternUnits', |
|
pointerEvents: 'pointer-events', |
|
points: 0, |
|
pointsAtX: 'pointsAtX', |
|
pointsAtY: 'pointsAtY', |
|
pointsAtZ: 'pointsAtZ', |
|
preserveAlpha: 'preserveAlpha', |
|
preserveAspectRatio: 'preserveAspectRatio', |
|
primitiveUnits: 'primitiveUnits', |
|
r: 0, |
|
radius: 0, |
|
refX: 'refX', |
|
refY: 'refY', |
|
renderingIntent: 'rendering-intent', |
|
repeatCount: 'repeatCount', |
|
repeatDur: 'repeatDur', |
|
requiredExtensions: 'requiredExtensions', |
|
requiredFeatures: 'requiredFeatures', |
|
restart: 0, |
|
result: 0, |
|
rotate: 0, |
|
rx: 0, |
|
ry: 0, |
|
scale: 0, |
|
seed: 0, |
|
shapeRendering: 'shape-rendering', |
|
slope: 0, |
|
spacing: 0, |
|
specularConstant: 'specularConstant', |
|
specularExponent: 'specularExponent', |
|
speed: 0, |
|
spreadMethod: 'spreadMethod', |
|
startOffset: 'startOffset', |
|
stdDeviation: 'stdDeviation', |
|
stemh: 0, |
|
stemv: 0, |
|
stitchTiles: 'stitchTiles', |
|
stopColor: 'stop-color', |
|
stopOpacity: 'stop-opacity', |
|
strikethroughPosition: 'strikethrough-position', |
|
strikethroughThickness: 'strikethrough-thickness', |
|
string: 0, |
|
stroke: 0, |
|
strokeDasharray: 'stroke-dasharray', |
|
strokeDashoffset: 'stroke-dashoffset', |
|
strokeLinecap: 'stroke-linecap', |
|
strokeLinejoin: 'stroke-linejoin', |
|
strokeMiterlimit: 'stroke-miterlimit', |
|
strokeOpacity: 'stroke-opacity', |
|
strokeWidth: 'stroke-width', |
|
surfaceScale: 'surfaceScale', |
|
systemLanguage: 'systemLanguage', |
|
tableValues: 'tableValues', |
|
targetX: 'targetX', |
|
targetY: 'targetY', |
|
textAnchor: 'text-anchor', |
|
textDecoration: 'text-decoration', |
|
textRendering: 'text-rendering', |
|
textLength: 'textLength', |
|
to: 0, |
|
transform: 0, |
|
u1: 0, |
|
u2: 0, |
|
underlinePosition: 'underline-position', |
|
underlineThickness: 'underline-thickness', |
|
unicode: 0, |
|
unicodeBidi: 'unicode-bidi', |
|
unicodeRange: 'unicode-range', |
|
unitsPerEm: 'units-per-em', |
|
vAlphabetic: 'v-alphabetic', |
|
vHanging: 'v-hanging', |
|
vIdeographic: 'v-ideographic', |
|
vMathematical: 'v-mathematical', |
|
values: 0, |
|
vectorEffect: 'vector-effect', |
|
version: 0, |
|
vertAdvY: 'vert-adv-y', |
|
vertOriginX: 'vert-origin-x', |
|
vertOriginY: 'vert-origin-y', |
|
viewBox: 'viewBox', |
|
viewTarget: 'viewTarget', |
|
visibility: 0, |
|
widths: 0, |
|
wordSpacing: 'word-spacing', |
|
writingMode: 'writing-mode', |
|
x: 0, |
|
xHeight: 'x-height', |
|
x1: 0, |
|
x2: 0, |
|
xChannelSelector: 'xChannelSelector', |
|
xlinkActuate: 'xlink:actuate', |
|
xlinkArcrole: 'xlink:arcrole', |
|
xlinkHref: 'xlink:href', |
|
xlinkRole: 'xlink:role', |
|
xlinkShow: 'xlink:show', |
|
xlinkTitle: 'xlink:title', |
|
xlinkType: 'xlink:type', |
|
xmlBase: 'xml:base', |
|
xmlns: 0, |
|
xmlnsXlink: 'xmlns:xlink', |
|
xmlLang: 'xml:lang', |
|
xmlSpace: 'xml:space', |
|
y: 0, |
|
y1: 0, |
|
y2: 0, |
|
yChannelSelector: 'yChannelSelector', |
|
z: 0, |
|
zoomAndPan: 'zoomAndPan' |
|
}; |
|
|
|
var SVGDOMPropertyConfig = { |
|
Properties: {}, |
|
DOMAttributeNamespaces: { |
|
xlinkActuate: NS.xlink, |
|
xlinkArcrole: NS.xlink, |
|
xlinkHref: NS.xlink, |
|
xlinkRole: NS.xlink, |
|
xlinkShow: NS.xlink, |
|
xlinkTitle: NS.xlink, |
|
xlinkType: NS.xlink, |
|
xmlBase: NS.xml, |
|
xmlLang: NS.xml, |
|
xmlSpace: NS.xml |
|
}, |
|
DOMAttributeNames: {} |
|
}; |
|
|
|
Object.keys(ATTRS).forEach(function (key) { |
|
SVGDOMPropertyConfig.Properties[key] = 0; |
|
if (ATTRS[key]) { |
|
SVGDOMPropertyConfig.DOMAttributeNames[key] = ATTRS[key]; |
|
} |
|
}); |
|
|
|
module.exports = SVGDOMPropertyConfig; |
|
},{}],85:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var EventPropagators = _dereq_(20); |
|
var ExecutionEnvironment = _dereq_(136); |
|
var ReactDOMComponentTree = _dereq_(34); |
|
var ReactInputSelection = _dereq_(62); |
|
var SyntheticEvent = _dereq_(91); |
|
|
|
var getActiveElement = _dereq_(145); |
|
var isTextInputElement = _dereq_(123); |
|
var shallowEqual = _dereq_(156); |
|
|
|
var skipSelectionChangeEvent = ExecutionEnvironment.canUseDOM && 'documentMode' in document && document.documentMode <= 11; |
|
|
|
var eventTypes = { |
|
select: { |
|
phasedRegistrationNames: { |
|
bubbled: 'onSelect', |
|
captured: 'onSelectCapture' |
|
}, |
|
dependencies: ['topBlur', 'topContextMenu', 'topFocus', 'topKeyDown', 'topKeyUp', 'topMouseDown', 'topMouseUp', 'topSelectionChange'] |
|
} |
|
}; |
|
|
|
var activeElement = null; |
|
var activeElementInst = null; |
|
var lastSelection = null; |
|
var mouseDown = false; |
|
|
|
// Track whether a listener exists for this plugin. If none exist, we do |
|
// not extract events. See #3639. |
|
var hasListener = 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 |
|
* @return {object} |
|
*/ |
|
function getSelection(node) { |
|
if ('selectionStart' in node && ReactInputSelection.hasSelectionCapabilities(node)) { |
|
return { |
|
start: node.selectionStart, |
|
end: node.selectionEnd |
|
}; |
|
} else if (window.getSelection) { |
|
var selection = window.getSelection(); |
|
return { |
|
anchorNode: selection.anchorNode, |
|
anchorOffset: selection.anchorOffset, |
|
focusNode: selection.focusNode, |
|
focusOffset: selection.focusOffset |
|
}; |
|
} else if (document.selection) { |
|
var range = document.selection.createRange(); |
|
return { |
|
parentElement: range.parentElement(), |
|
text: range.text, |
|
top: range.boundingTop, |
|
left: range.boundingLeft |
|
}; |
|
} |
|
} |
|
|
|
/** |
|
* Poll selection to see whether it's changed. |
|
* |
|
* @param {object} nativeEvent |
|
* @return {?SyntheticEvent} |
|
*/ |
|
function constructSelectEvent(nativeEvent, nativeEventTarget) { |
|
// 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 null; |
|
} |
|
|
|
// Only fire when selection has actually changed. |
|
var currentSelection = getSelection(activeElement); |
|
if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) { |
|
lastSelection = currentSelection; |
|
|
|
var syntheticEvent = SyntheticEvent.getPooled(eventTypes.select, activeElementInst, nativeEvent, nativeEventTarget); |
|
|
|
syntheticEvent.type = 'select'; |
|
syntheticEvent.target = activeElement; |
|
|
|
EventPropagators.accumulateTwoPhaseDispatches(syntheticEvent); |
|
|
|
return syntheticEvent; |
|
} |
|
|
|
return null; |
|
} |
|
|
|
/** |
|
* 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, |
|
|
|
extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { |
|
if (!hasListener) { |
|
return null; |
|
} |
|
|
|
var targetNode = targetInst ? ReactDOMComponentTree.getNodeFromInstance(targetInst) : window; |
|
|
|
switch (topLevelType) { |
|
// Track the input node that has focus. |
|
case 'topFocus': |
|
if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') { |
|
activeElement = targetNode; |
|
activeElementInst = targetInst; |
|
lastSelection = null; |
|
} |
|
break; |
|
case 'topBlur': |
|
activeElement = null; |
|
activeElementInst = null; |
|
lastSelection = null; |
|
break; |
|
|
|
// Don't fire the event while the user is dragging. This matches the |
|
// semantics of the native select event. |
|
case 'topMouseDown': |
|
mouseDown = true; |
|
break; |
|
case 'topContextMenu': |
|
case 'topMouseUp': |
|
mouseDown = false; |
|
return constructSelectEvent(nativeEvent, nativeEventTarget); |
|
|
|
// Chrome and IE fire non-standard event when selection is changed (and |
|
// sometimes when it hasn't). IE's event fires out of order with respect |
|
// to key and input events on deletion, so we discard it. |
|
// |
|
// 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. |
|
// This is also our approach for IE handling, for the reason above. |
|
case 'topSelectionChange': |
|
if (skipSelectionChangeEvent) { |
|
break; |
|
} |
|
// falls through |
|
case 'topKeyDown': |
|
case 'topKeyUp': |
|
return constructSelectEvent(nativeEvent, nativeEventTarget); |
|
} |
|
|
|
return null; |
|
}, |
|
|
|
didPutListener: function (inst, registrationName, listener) { |
|
if (registrationName === 'onSelect') { |
|
hasListener = true; |
|
} |
|
} |
|
}; |
|
|
|
module.exports = SelectEventPlugin; |
|
},{"123":123,"136":136,"145":145,"156":156,"20":20,"34":34,"62":62,"91":91}],86:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125); |
|
|
|
var EventListener = _dereq_(135); |
|
var EventPropagators = _dereq_(20); |
|
var ReactDOMComponentTree = _dereq_(34); |
|
var SyntheticAnimationEvent = _dereq_(87); |
|
var SyntheticClipboardEvent = _dereq_(88); |
|
var SyntheticEvent = _dereq_(91); |
|
var SyntheticFocusEvent = _dereq_(92); |
|
var SyntheticKeyboardEvent = _dereq_(94); |
|
var SyntheticMouseEvent = _dereq_(95); |
|
var SyntheticDragEvent = _dereq_(90); |
|
var SyntheticTouchEvent = _dereq_(96); |
|
var SyntheticTransitionEvent = _dereq_(97); |
|
var SyntheticUIEvent = _dereq_(98); |
|
var SyntheticWheelEvent = _dereq_(99); |
|
|
|
var emptyFunction = _dereq_(142); |
|
var getEventCharCode = _dereq_(111); |
|
var invariant = _dereq_(150); |
|
|
|
/** |
|
* Turns |
|
* ['abort', ...] |
|
* into |
|
* eventTypes = { |
|
* 'abort': { |
|
* phasedRegistrationNames: { |
|
* bubbled: 'onAbort', |
|
* captured: 'onAbortCapture', |
|
* }, |
|
* dependencies: ['topAbort'], |
|
* }, |
|
* ... |
|
* }; |
|
* topLevelEventsToDispatchConfig = { |
|
* 'topAbort': { sameConfig } |
|
* }; |
|
*/ |
|
var eventTypes = {}; |
|
var topLevelEventsToDispatchConfig = {}; |
|
['abort', 'animationEnd', 'animationIteration', 'animationStart', 'blur', 'canPlay', 'canPlayThrough', 'click', 'contextMenu', 'copy', 'cut', 'doubleClick', 'drag', 'dragEnd', 'dragEnter', 'dragExit', 'dragLeave', 'dragOver', 'dragStart', 'drop', 'durationChange', 'emptied', 'encrypted', 'ended', 'error', 'focus', 'input', 'invalid', 'keyDown', 'keyPress', 'keyUp', 'load', 'loadedData', 'loadedMetadata', 'loadStart', 'mouseDown', 'mouseMove', 'mouseOut', 'mouseOver', 'mouseUp', 'paste', 'pause', 'play', 'playing', 'progress', 'rateChange', 'reset', 'scroll', 'seeked', 'seeking', 'stalled', 'submit', 'suspend', 'timeUpdate', 'touchCancel', 'touchEnd', 'touchMove', 'touchStart', 'transitionEnd', 'volumeChange', 'waiting', 'wheel'].forEach(function (event) { |
|
var capitalizedEvent = event[0].toUpperCase() + event.slice(1); |
|
var onEvent = 'on' + capitalizedEvent; |
|
var topEvent = 'top' + capitalizedEvent; |
|
|
|
var type = { |
|
phasedRegistrationNames: { |
|
bubbled: onEvent, |
|
captured: onEvent + 'Capture' |
|
}, |
|
dependencies: [topEvent] |
|
}; |
|
eventTypes[event] = type; |
|
topLevelEventsToDispatchConfig[topEvent] = type; |
|
}); |
|
|
|
var onClickListeners = {}; |
|
|
|
function getDictionaryKey(inst) { |
|
// Prevents V8 performance issue: |
|
// https://github.com/facebook/react/pull/7232 |
|
return '.' + inst._rootNodeID; |
|
} |
|
|
|
function isInteractive(tag) { |
|
return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea'; |
|
} |
|
|
|
var SimpleEventPlugin = { |
|
|
|
eventTypes: eventTypes, |
|
|
|
extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) { |
|
var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType]; |
|
if (!dispatchConfig) { |
|
return null; |
|
} |
|
var EventConstructor; |
|
switch (topLevelType) { |
|
case 'topAbort': |
|
case 'topCanPlay': |
|
case 'topCanPlayThrough': |
|
case 'topDurationChange': |
|
case 'topEmptied': |
|
case 'topEncrypted': |
|
case 'topEnded': |
|
case 'topError': |
|
case 'topInput': |
|
case 'topInvalid': |
|
case 'topLoad': |
|
case 'topLoadedData': |
|
case 'topLoadedMetadata': |
|
case 'topLoadStart': |
|
case 'topPause': |
|
case 'topPlay': |
|
case 'topPlaying': |
|
case 'topProgress': |
|
case 'topRateChange': |
|
case 'topReset': |
|
case 'topSeeked': |
|
case 'topSeeking': |
|
case 'topStalled': |
|
case 'topSubmit': |
|
case 'topSuspend': |
|
case 'topTimeUpdate': |
|
case 'topVolumeChange': |
|
case 'topWaiting': |
|
// HTML Events |
|
// @see http://www.w3.org/TR/html5/index.html#events-0 |
|
EventConstructor = SyntheticEvent; |
|
break; |
|
case 'topKeyPress': |
|
// Firefox creates a keypress event for function keys too. This removes |
|
// the unwanted keypress events. Enter is however both printable and |
|
// non-printable. One would expect Tab to be as well (but it isn't). |
|
if (getEventCharCode(nativeEvent) === 0) { |
|
return null; |
|
} |
|
/* falls through */ |
|
case 'topKeyDown': |
|
case 'topKeyUp': |
|
EventConstructor = SyntheticKeyboardEvent; |
|
break; |
|
case 'topBlur': |
|
case 'topFocus': |
|
EventConstructor = SyntheticFocusEvent; |
|
break; |
|
case '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 'topDoubleClick': |
|
case 'topMouseDown': |
|
case 'topMouseMove': |
|
case 'topMouseUp': |
|
// TODO: Disabled elements should not respond to mouse events |
|
/* falls through */ |
|
case 'topMouseOut': |
|
case 'topMouseOver': |
|
case 'topContextMenu': |
|
EventConstructor = SyntheticMouseEvent; |
|
break; |
|
case 'topDrag': |
|
case 'topDragEnd': |
|
case 'topDragEnter': |
|
case 'topDragExit': |
|
case 'topDragLeave': |
|
case 'topDragOver': |
|
case 'topDragStart': |
|
case 'topDrop': |
|
EventConstructor = SyntheticDragEvent; |
|
break; |
|
case 'topTouchCancel': |
|
case 'topTouchEnd': |
|
case 'topTouchMove': |
|
case 'topTouchStart': |
|
EventConstructor = SyntheticTouchEvent; |
|
break; |
|
case 'topAnimationEnd': |
|
case 'topAnimationIteration': |
|
case 'topAnimationStart': |
|
EventConstructor = SyntheticAnimationEvent; |
|
break; |
|
case 'topTransitionEnd': |
|
EventConstructor = SyntheticTransitionEvent; |
|
break; |
|
case 'topScroll': |
|
EventConstructor = SyntheticUIEvent; |
|
break; |
|
case 'topWheel': |
|
EventConstructor = SyntheticWheelEvent; |
|
break; |
|
case 'topCopy': |
|
case 'topCut': |
|
case 'topPaste': |
|
EventConstructor = SyntheticClipboardEvent; |
|
break; |
|
} |
|
!EventConstructor ? "development" !== 'production' ? invariant(false, 'SimpleEventPlugin: Unhandled event type, `%s`.', topLevelType) : _prodInvariant('86', topLevelType) : void 0; |
|
var event = EventConstructor.getPooled(dispatchConfig, targetInst, nativeEvent, nativeEventTarget); |
|
EventPropagators.accumulateTwoPhaseDispatches(event); |
|
return event; |
|
}, |
|
|
|
didPutListener: function (inst, registrationName, listener) { |
|
// 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. |
|
// http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html |
|
if (registrationName === 'onClick' && !isInteractive(inst._tag)) { |
|
var key = getDictionaryKey(inst); |
|
var node = ReactDOMComponentTree.getNodeFromInstance(inst); |
|
if (!onClickListeners[key]) { |
|
onClickListeners[key] = EventListener.listen(node, 'click', emptyFunction); |
|
} |
|
} |
|
}, |
|
|
|
willDeleteListener: function (inst, registrationName) { |
|
if (registrationName === 'onClick' && !isInteractive(inst._tag)) { |
|
var key = getDictionaryKey(inst); |
|
onClickListeners[key].remove(); |
|
delete onClickListeners[key]; |
|
} |
|
} |
|
|
|
}; |
|
|
|
module.exports = SimpleEventPlugin; |
|
},{"111":111,"125":125,"135":135,"142":142,"150":150,"20":20,"34":34,"87":87,"88":88,"90":90,"91":91,"92":92,"94":94,"95":95,"96":96,"97":97,"98":98,"99":99}],87:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var SyntheticEvent = _dereq_(91); |
|
|
|
/** |
|
* @interface Event |
|
* @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface |
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent |
|
*/ |
|
var AnimationEventInterface = { |
|
animationName: null, |
|
elapsedTime: null, |
|
pseudoElement: 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 SyntheticAnimationEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { |
|
return SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); |
|
} |
|
|
|
SyntheticEvent.augmentClass(SyntheticAnimationEvent, AnimationEventInterface); |
|
|
|
module.exports = SyntheticAnimationEvent; |
|
},{"91":91}],88:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var SyntheticEvent = _dereq_(91); |
|
|
|
/** |
|
* @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, nativeEventTarget) { |
|
return SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); |
|
} |
|
|
|
SyntheticEvent.augmentClass(SyntheticClipboardEvent, ClipboardEventInterface); |
|
|
|
module.exports = SyntheticClipboardEvent; |
|
},{"91":91}],89:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var SyntheticEvent = _dereq_(91); |
|
|
|
/** |
|
* @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, nativeEventTarget) { |
|
return SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); |
|
} |
|
|
|
SyntheticEvent.augmentClass(SyntheticCompositionEvent, CompositionEventInterface); |
|
|
|
module.exports = SyntheticCompositionEvent; |
|
},{"91":91}],90:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var SyntheticMouseEvent = _dereq_(95); |
|
|
|
/** |
|
* @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, nativeEventTarget) { |
|
return SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); |
|
} |
|
|
|
SyntheticMouseEvent.augmentClass(SyntheticDragEvent, DragEventInterface); |
|
|
|
module.exports = SyntheticDragEvent; |
|
},{"95":95}],91:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _assign = _dereq_(158); |
|
|
|
var PooledClass = _dereq_(25); |
|
|
|
var emptyFunction = _dereq_(142); |
|
var warning = _dereq_(157); |
|
|
|
var didWarnForAddedNewProperty = false; |
|
var isProxySupported = typeof Proxy === 'function'; |
|
|
|
var shouldBeReleasedProperties = ['dispatchConfig', '_targetInst', 'nativeEvent', 'isDefaultPrevented', 'isPropagationStopped', '_dispatchListeners', '_dispatchInstances']; |
|
|
|
/** |
|
* @interface Event |
|
* @see http://www.w3.org/TR/DOM-Level-3-Events/ |
|
*/ |
|
var EventInterface = { |
|
type: null, |
|
target: null, |
|
// 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 {*} targetInst Marker identifying the event target. |
|
* @param {object} nativeEvent Native browser event. |
|
* @param {DOMEventTarget} nativeEventTarget Target node. |
|
*/ |
|
function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) { |
|
if ("development" !== 'production') { |
|
// these have a getter/setter for warnings |
|
delete this.nativeEvent; |
|
delete this.preventDefault; |
|
delete this.stopPropagation; |
|
} |
|
|
|
this.dispatchConfig = dispatchConfig; |
|
this._targetInst = targetInst; |
|
this.nativeEvent = nativeEvent; |
|
|
|
var Interface = this.constructor.Interface; |
|
for (var propName in Interface) { |
|
if (!Interface.hasOwnProperty(propName)) { |
|
continue; |
|
} |
|
if ("development" !== 'production') { |
|
delete this[propName]; // this has a getter/setter for warnings |
|
} |
|
var normalize = Interface[propName]; |
|
if (normalize) { |
|
this[propName] = normalize(nativeEvent); |
|
} else { |
|
if (propName === 'target') { |
|
this.target = nativeEventTarget; |
|
} 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; |
|
return this; |
|
} |
|
|
|
_assign(SyntheticEvent.prototype, { |
|
|
|
preventDefault: function () { |
|
this.defaultPrevented = true; |
|
var event = this.nativeEvent; |
|
if (!event) { |
|
return; |
|
} |
|
|
|
if (event.preventDefault) { |
|
event.preventDefault(); |
|
} else if (typeof event.returnValue !== 'unknown') { |
|
// eslint-disable-line valid-typeof |
|
event.returnValue = false; |
|
} |
|
this.isDefaultPrevented = emptyFunction.thatReturnsTrue; |
|
}, |
|
|
|
stopPropagation: function () { |
|
var event = this.nativeEvent; |
|
if (!event) { |
|
return; |
|
} |
|
|
|
if (event.stopPropagation) { |
|
event.stopPropagation(); |
|
} else if (typeof event.cancelBubble !== 'unknown') { |
|
// eslint-disable-line valid-typeof |
|
// The ChangeEventPlugin registers a "propertychange" event for |
|
// IE. This event does not support bubbling or cancelling, and |
|
// any references to cancelBubble throw "Member not found". A |
|
// typeof check of "unknown" circumvents this issue (and is also |
|
// IE specific). |
|
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) { |
|
if ("development" !== 'production') { |
|
Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName])); |
|
} else { |
|
this[propName] = null; |
|
} |
|
} |
|
for (var i = 0; i < shouldBeReleasedProperties.length; i++) { |
|
this[shouldBeReleasedProperties[i]] = null; |
|
} |
|
if ("development" !== 'production') { |
|
Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null)); |
|
Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', emptyFunction)); |
|
Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', emptyFunction)); |
|
} |
|
} |
|
|
|
}); |
|
|
|
SyntheticEvent.Interface = EventInterface; |
|
|
|
if ("development" !== 'production') { |
|
if (isProxySupported) { |
|
/*eslint-disable no-func-assign */ |
|
SyntheticEvent = new Proxy(SyntheticEvent, { |
|
construct: function (target, args) { |
|
return this.apply(target, Object.create(target.prototype), args); |
|
}, |
|
apply: function (constructor, that, args) { |
|
return new Proxy(constructor.apply(that, args), { |
|
set: function (target, prop, value) { |
|
if (prop !== 'isPersistent' && !target.constructor.Interface.hasOwnProperty(prop) && shouldBeReleasedProperties.indexOf(prop) === -1) { |
|
"development" !== 'production' ? warning(didWarnForAddedNewProperty || target.isPersistent(), 'This synthetic event is reused for performance reasons. If you\'re ' + 'seeing this, you\'re adding a new property in the synthetic event object. ' + 'The property is never released. See ' + 'https://fb.me/react-event-pooling for more information.') : void 0; |
|
didWarnForAddedNewProperty = true; |
|
} |
|
target[prop] = value; |
|
return true; |
|
} |
|
}); |
|
} |
|
}); |
|
/*eslint-enable no-func-assign */ |
|
} |
|
} |
|
/** |
|
* Helper to reduce boilerplate when creating subclasses. |
|
* |
|
* @param {function} Class |
|
* @param {?object} Interface |
|
*/ |
|
SyntheticEvent.augmentClass = function (Class, Interface) { |
|
var Super = this; |
|
|
|
var E = function () {}; |
|
E.prototype = Super.prototype; |
|
var prototype = new E(); |
|
|
|
_assign(prototype, Class.prototype); |
|
Class.prototype = prototype; |
|
Class.prototype.constructor = Class; |
|
|
|
Class.Interface = _assign({}, Super.Interface, Interface); |
|
Class.augmentClass = Super.augmentClass; |
|
|
|
PooledClass.addPoolingTo(Class, PooledClass.fourArgumentPooler); |
|
}; |
|
|
|
PooledClass.addPoolingTo(SyntheticEvent, PooledClass.fourArgumentPooler); |
|
|
|
module.exports = SyntheticEvent; |
|
|
|
/** |
|
* Helper to nullify syntheticEvent instance properties when destructing |
|
* |
|
* @param {object} SyntheticEvent |
|
* @param {String} propName |
|
* @return {object} defineProperty object |
|
*/ |
|
function getPooledWarningPropertyDefinition(propName, getVal) { |
|
var isFunction = typeof getVal === 'function'; |
|
return { |
|
configurable: true, |
|
set: set, |
|
get: get |
|
}; |
|
|
|
function set(val) { |
|
var action = isFunction ? 'setting the method' : 'setting the property'; |
|
warn(action, 'This is effectively a no-op'); |
|
return val; |
|
} |
|
|
|
function get() { |
|
var action = isFunction ? 'accessing the method' : 'accessing the property'; |
|
var result = isFunction ? 'This is a no-op function' : 'This is set to null'; |
|
warn(action, result); |
|
return getVal; |
|
} |
|
|
|
function warn(action, result) { |
|
var warningCondition = false; |
|
"development" !== 'production' ? warning(warningCondition, 'This synthetic event is reused for performance reasons. If you\'re seeing this, ' + 'you\'re %s `%s` on a released/nullified synthetic event. %s. ' + 'If you must keep the original synthetic event around, use event.persist(). ' + 'See https://fb.me/react-event-pooling for more information.', action, propName, result) : void 0; |
|
} |
|
} |
|
},{"142":142,"157":157,"158":158,"25":25}],92:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var SyntheticUIEvent = _dereq_(98); |
|
|
|
/** |
|
* @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, nativeEventTarget) { |
|
return SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); |
|
} |
|
|
|
SyntheticUIEvent.augmentClass(SyntheticFocusEvent, FocusEventInterface); |
|
|
|
module.exports = SyntheticFocusEvent; |
|
},{"98":98}],93:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var SyntheticEvent = _dereq_(91); |
|
|
|
/** |
|
* @interface Event |
|
* @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105 |
|
* /#events-inputevents |
|
*/ |
|
var InputEventInterface = { |
|
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 SyntheticInputEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { |
|
return SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); |
|
} |
|
|
|
SyntheticEvent.augmentClass(SyntheticInputEvent, InputEventInterface); |
|
|
|
module.exports = SyntheticInputEvent; |
|
},{"91":91}],94:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var SyntheticUIEvent = _dereq_(98); |
|
|
|
var getEventCharCode = _dereq_(111); |
|
var getEventKey = _dereq_(112); |
|
var getEventModifierState = _dereq_(113); |
|
|
|
/** |
|
* @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, |
|
getModifierState: getEventModifierState, |
|
// Legacy Interface |
|
charCode: function (event) { |
|
// `charCode` is the result of a KeyPress event and represents the value of |
|
// the actual printable character. |
|
|
|
// KeyPress is deprecated, but its replacement is not yet final and not |
|
// implemented in any major browser. Only KeyPress has charCode. |
|
if (event.type === 'keypress') { |
|
return getEventCharCode(event); |
|
} |
|
return 0; |
|
}, |
|
keyCode: function (event) { |
|
// `keyCode` is the result of a KeyDown/Up event and represents the value of |
|
// physical keyboard key. |
|
|
|
// The actual meaning of the value depends on the users' keyboard layout |
|
// which cannot be detected. Assuming that it is a US keyboard layout |
|
// provides a surprisingly accurate mapping for US and European users. |
|
// Due to this, it is left to the user to implement at this time. |
|
if (event.type === 'keydown' || event.type === 'keyup') { |
|
return event.keyCode; |
|
} |
|
return 0; |
|
}, |
|
which: function (event) { |
|
// `which` is an alias for either `keyCode` or `charCode` depending on the |
|
// type of the event. |
|
if (event.type === 'keypress') { |
|
return getEventCharCode(event); |
|
} |
|
if (event.type === 'keydown' || event.type === 'keyup') { |
|
return event.keyCode; |
|
} |
|
return 0; |
|
} |
|
}; |
|
|
|
/** |
|
* @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, nativeEventTarget) { |
|
return SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); |
|
} |
|
|
|
SyntheticUIEvent.augmentClass(SyntheticKeyboardEvent, KeyboardEventInterface); |
|
|
|
module.exports = SyntheticKeyboardEvent; |
|
},{"111":111,"112":112,"113":113,"98":98}],95:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var SyntheticUIEvent = _dereq_(98); |
|
var ViewportMetrics = _dereq_(101); |
|
|
|
var getEventModifierState = _dereq_(113); |
|
|
|
/** |
|
* @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, |
|
getModifierState: getEventModifierState, |
|
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, nativeEventTarget) { |
|
return SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); |
|
} |
|
|
|
SyntheticUIEvent.augmentClass(SyntheticMouseEvent, MouseEventInterface); |
|
|
|
module.exports = SyntheticMouseEvent; |
|
},{"101":101,"113":113,"98":98}],96:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var SyntheticUIEvent = _dereq_(98); |
|
|
|
var getEventModifierState = _dereq_(113); |
|
|
|
/** |
|
* @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, |
|
getModifierState: getEventModifierState |
|
}; |
|
|
|
/** |
|
* @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, nativeEventTarget) { |
|
return SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); |
|
} |
|
|
|
SyntheticUIEvent.augmentClass(SyntheticTouchEvent, TouchEventInterface); |
|
|
|
module.exports = SyntheticTouchEvent; |
|
},{"113":113,"98":98}],97:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var SyntheticEvent = _dereq_(91); |
|
|
|
/** |
|
* @interface Event |
|
* @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events- |
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent |
|
*/ |
|
var TransitionEventInterface = { |
|
propertyName: null, |
|
elapsedTime: null, |
|
pseudoElement: 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 SyntheticTransitionEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) { |
|
return SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); |
|
} |
|
|
|
SyntheticEvent.augmentClass(SyntheticTransitionEvent, TransitionEventInterface); |
|
|
|
module.exports = SyntheticTransitionEvent; |
|
},{"91":91}],98:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var SyntheticEvent = _dereq_(91); |
|
|
|
var getEventTarget = _dereq_(114); |
|
|
|
/** |
|
* @interface UIEvent |
|
* @see http://www.w3.org/TR/DOM-Level-3-Events/ |
|
*/ |
|
var UIEventInterface = { |
|
view: function (event) { |
|
if (event.view) { |
|
return event.view; |
|
} |
|
|
|
var target = getEventTarget(event); |
|
if (target.window === target) { |
|
// target is a window object |
|
return target; |
|
} |
|
|
|
var doc = target.ownerDocument; |
|
// TODO: Figure out why `ownerDocument` is sometimes undefined in IE8. |
|
if (doc) { |
|
return doc.defaultView || doc.parentWindow; |
|
} else { |
|
return window; |
|
} |
|
}, |
|
detail: function (event) { |
|
return event.detail || 0; |
|
} |
|
}; |
|
|
|
/** |
|
* @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, nativeEventTarget) { |
|
return SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); |
|
} |
|
|
|
SyntheticEvent.augmentClass(SyntheticUIEvent, UIEventInterface); |
|
|
|
module.exports = SyntheticUIEvent; |
|
},{"114":114,"91":91}],99:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var SyntheticMouseEvent = _dereq_(95); |
|
|
|
/** |
|
* @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, nativeEventTarget) { |
|
return SyntheticMouseEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget); |
|
} |
|
|
|
SyntheticMouseEvent.augmentClass(SyntheticWheelEvent, WheelEventInterface); |
|
|
|
module.exports = SyntheticWheelEvent; |
|
},{"95":95}],100:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125); |
|
|
|
var invariant = _dereq_(150); |
|
|
|
var OBSERVED_ERROR = {}; |
|
|
|
/** |
|
* `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> |
|
* |
|
* 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 updates. |
|
* |
|
* 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 TransactionImpl = { |
|
/** |
|
* 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.length = 0; |
|
} else { |
|
this.wrapperInitData = []; |
|
} |
|
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. The optional arguments helps prevent the need |
|
* to bind in many cases. |
|
* |
|
* @param {function} method Member of scope to call. |
|
* @param {Object} scope Scope to invoke from. |
|
* @param {Object?=} a Argument to pass to the method. |
|
* @param {Object?=} b Argument to pass to the method. |
|
* @param {Object?=} c Argument to pass to the method. |
|
* @param {Object?=} d Argument to pass to the method. |
|
* @param {Object?=} e Argument to pass to the method. |
|
* @param {Object?=} f Argument to pass to the method. |
|
* |
|
* @return {*} Return value from `method`. |
|
*/ |
|
perform: function (method, scope, a, b, c, d, e, f) { |
|
!!this.isInTransaction() ? "development" !== 'production' ? invariant(false, 'Transaction.perform(...): Cannot initialize a transaction when there is already an outstanding transaction.') : _prodInvariant('27') : void 0; |
|
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 { |
|
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; |
|
for (var i = startIndex; i < transactionWrappers.length; i++) { |
|
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] = OBSERVED_ERROR; |
|
this.wrapperInitData[i] = wrapper.initialize ? wrapper.initialize.call(this) : null; |
|
} finally { |
|
if (this.wrapperInitData[i] === 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) { |
|
!this.isInTransaction() ? "development" !== 'production' ? invariant(false, 'Transaction.closeAll(): Cannot close transaction when none are open.') : _prodInvariant('28') : void 0; |
|
var transactionWrappers = this.transactionWrappers; |
|
for (var i = startIndex; i < transactionWrappers.length; i++) { |
|
var wrapper = transactionWrappers[i]; |
|
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 !== OBSERVED_ERROR && wrapper.close) { |
|
wrapper.close.call(this, initData); |
|
} |
|
errorThrown = false; |
|
} finally { |
|
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; |
|
} |
|
}; |
|
|
|
module.exports = TransactionImpl; |
|
},{"125":125,"150":150}],101:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var ViewportMetrics = { |
|
|
|
currentScrollLeft: 0, |
|
|
|
currentScrollTop: 0, |
|
|
|
refreshScrollValues: function (scrollPosition) { |
|
ViewportMetrics.currentScrollLeft = scrollPosition.x; |
|
ViewportMetrics.currentScrollTop = scrollPosition.y; |
|
} |
|
|
|
}; |
|
|
|
module.exports = ViewportMetrics; |
|
},{}],102:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2014-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125); |
|
|
|
var invariant = _dereq_(150); |
|
|
|
/** |
|
* Accumulates items that must not be null or undefined into the first one. This |
|
* is used to conserve memory by avoiding array allocations, and thus sacrifices |
|
* API cleanness. Since `current` can be null before being passed in and not |
|
* null after this function, make sure to assign it back to `current`: |
|
* |
|
* `a = accumulateInto(a, b);` |
|
* |
|
* This API should be sparingly used. Try `accumulate` for something cleaner. |
|
* |
|
* @return {*|array<*>} An accumulation of items. |
|
*/ |
|
|
|
function accumulateInto(current, next) { |
|
!(next != null) ? "development" !== 'production' ? invariant(false, 'accumulateInto(...): Accumulated items must not be null or undefined.') : _prodInvariant('30') : void 0; |
|
|
|
if (current == null) { |
|
return next; |
|
} |
|
|
|
// 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). |
|
if (Array.isArray(current)) { |
|
if (Array.isArray(next)) { |
|
current.push.apply(current, next); |
|
return current; |
|
} |
|
current.push(next); |
|
return current; |
|
} |
|
|
|
if (Array.isArray(next)) { |
|
// A bit too dangerous to mutate `next`. |
|
return [current].concat(next); |
|
} |
|
|
|
return [current, next]; |
|
} |
|
|
|
module.exports = accumulateInto; |
|
},{"125":125,"150":150}],103:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var MOD = 65521; |
|
|
|
// adler32 is not cryptographically strong, and is only used to sanity check that |
|
// markup generated on the server matches the markup generated on the client. |
|
// This implementation (a modified version of the SheetJS version) has been optimized |
|
// for our use case, at the expense of conforming to the adler32 specification |
|
// for non-ascii inputs. |
|
function adler32(data) { |
|
var a = 1; |
|
var b = 0; |
|
var i = 0; |
|
var l = data.length; |
|
var m = l & ~0x3; |
|
while (i < m) { |
|
var n = Math.min(i + 4096, m); |
|
for (; i < n; i += 4) { |
|
b += (a += data.charCodeAt(i)) + (a += data.charCodeAt(i + 1)) + (a += data.charCodeAt(i + 2)) + (a += data.charCodeAt(i + 3)); |
|
} |
|
a %= MOD; |
|
b %= MOD; |
|
} |
|
for (; i < l; i++) { |
|
b += a += data.charCodeAt(i); |
|
} |
|
a %= MOD; |
|
b %= MOD; |
|
return a | b << 16; |
|
} |
|
|
|
module.exports = adler32; |
|
},{}],104:[function(_dereq_,module,exports){ |
|
(function (process){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125); |
|
|
|
var ReactPropTypeLocationNames = _dereq_(72); |
|
var ReactPropTypesSecret = _dereq_(73); |
|
|
|
var invariant = _dereq_(150); |
|
var warning = _dereq_(157); |
|
|
|
var ReactComponentTreeHook; |
|
|
|
if (typeof process !== 'undefined' && process.env && "development" === 'test') { |
|
// Temporary hack. |
|
// Inline requires don't work well with Jest: |
|
// https://github.com/facebook/react/issues/7240 |
|
// Remove the inline requires when we don't need them anymore: |
|
// https://github.com/facebook/react/pull/7178 |
|
ReactComponentTreeHook = _dereq_(132); |
|
} |
|
|
|
var loggedTypeFailures = {}; |
|
|
|
/** |
|
* Assert that the values match with the type specs. |
|
* Error messages are memorized and will only be shown once. |
|
* |
|
* @param {object} typeSpecs Map of name to a ReactPropType |
|
* @param {object} values Runtime values that need to be type-checked |
|
* @param {string} location e.g. "prop", "context", "child context" |
|
* @param {string} componentName Name of the component for error messages. |
|
* @param {?object} element The React element that is being type-checked |
|
* @param {?number} debugID The React component instance that is being type-checked |
|
* @private |
|
*/ |
|
function checkReactTypeSpec(typeSpecs, values, location, componentName, element, debugID) { |
|
for (var typeSpecName in typeSpecs) { |
|
if (typeSpecs.hasOwnProperty(typeSpecName)) { |
|
var error; |
|
// Prop type validation may throw. In case they do, we don't want to |
|
// fail the render phase where it didn't fail before. So we log it. |
|
// After these have been cleaned up, we'll let them throw. |
|
try { |
|
// This is intentionally an invariant that gets caught. It's the same |
|
// behavior as without this statement except with a better message. |
|
!(typeof typeSpecs[typeSpecName] === 'function') ? "development" !== 'production' ? invariant(false, '%s: %s type `%s` is invalid; it must be a function, usually from React.PropTypes.', componentName || 'React class', ReactPropTypeLocationNames[location], typeSpecName) : _prodInvariant('84', componentName || 'React class', ReactPropTypeLocationNames[location], typeSpecName) : void 0; |
|
error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret); |
|
} catch (ex) { |
|
error = ex; |
|
} |
|
"development" !== 'production' ? warning(!error || error instanceof Error, '%s: type specification of %s `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', ReactPropTypeLocationNames[location], typeSpecName, typeof error) : void 0; |
|
if (error instanceof Error && !(error.message in loggedTypeFailures)) { |
|
// Only monitor this failure once because there tends to be a lot of the |
|
// same error. |
|
loggedTypeFailures[error.message] = true; |
|
|
|
var componentStackInfo = ''; |
|
|
|
if ("development" !== 'production') { |
|
if (!ReactComponentTreeHook) { |
|
ReactComponentTreeHook = _dereq_(132); |
|
} |
|
if (debugID !== null) { |
|
componentStackInfo = ReactComponentTreeHook.getStackAddendumByID(debugID); |
|
} else if (element !== null) { |
|
componentStackInfo = ReactComponentTreeHook.getCurrentStackAddendum(element); |
|
} |
|
} |
|
|
|
"development" !== 'production' ? warning(false, 'Failed %s type: %s%s', location, error.message, componentStackInfo) : void 0; |
|
} |
|
} |
|
} |
|
} |
|
|
|
module.exports = checkReactTypeSpec; |
|
}).call(this,undefined) |
|
},{"125":125,"132":132,"150":150,"157":157,"72":72,"73":73}],105:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
/* globals MSApp */ |
|
|
|
'use strict'; |
|
|
|
/** |
|
* Create a function which has 'unsafe' privileges (required by windows8 apps) |
|
*/ |
|
|
|
var createMicrosoftUnsafeLocalFunction = function (func) { |
|
if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) { |
|
return function (arg0, arg1, arg2, arg3) { |
|
MSApp.execUnsafeLocalFunction(function () { |
|
return func(arg0, arg1, arg2, arg3); |
|
}); |
|
}; |
|
} else { |
|
return func; |
|
} |
|
}; |
|
|
|
module.exports = createMicrosoftUnsafeLocalFunction; |
|
},{}],106:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var CSSProperty = _dereq_(4); |
|
var warning = _dereq_(157); |
|
|
|
var isUnitlessNumber = CSSProperty.isUnitlessNumber; |
|
var styleWarnings = {}; |
|
|
|
/** |
|
* Convert a value into the proper css writable value. The style name `name` |
|
* should be logical (no hyphens), as specified |
|
* in `CSSProperty.isUnitlessNumber`. |
|
* |
|
* @param {string} name CSS property name such as `topMargin`. |
|
* @param {*} value CSS property value such as `10px`. |
|
* @param {ReactDOMComponent} component |
|
* @return {string} Normalized style value with dimensions applied. |
|
*/ |
|
function dangerousStyleValue(name, value, component) { |
|
// 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 || isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name]) { |
|
return '' + value; // cast to string |
|
} |
|
|
|
if (typeof value === 'string') { |
|
if ("development" !== 'production') { |
|
// Allow '0' to pass through without warning. 0 is already special and |
|
// doesn't require units, so we don't need to warn about it. |
|
if (component && value !== '0') { |
|
var owner = component._currentElement._owner; |
|
var ownerName = owner ? owner.getName() : null; |
|
if (ownerName && !styleWarnings[ownerName]) { |
|
styleWarnings[ownerName] = {}; |
|
} |
|
var warned = false; |
|
if (ownerName) { |
|
var warnings = styleWarnings[ownerName]; |
|
warned = warnings[name]; |
|
if (!warned) { |
|
warnings[name] = true; |
|
} |
|
} |
|
if (!warned) { |
|
"development" !== 'production' ? warning(false, 'a `%s` tag (owner: `%s`) was passed a numeric string value ' + 'for CSS property `%s` (value: `%s`) which will be treated ' + 'as a unitless number in a future version of React.', component._currentElement.type, ownerName || 'unknown', name, value) : void 0; |
|
} |
|
} |
|
} |
|
value = value.trim(); |
|
} |
|
return value + 'px'; |
|
} |
|
|
|
module.exports = dangerousStyleValue; |
|
},{"157":157,"4":4}],107:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2016-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* Based on the escape-html library, which is used under the MIT License below: |
|
* |
|
* Copyright (c) 2012-2013 TJ Holowaychuk |
|
* Copyright (c) 2015 Andreas Lubbe |
|
* Copyright (c) 2015 Tiancheng "Timothy" Gu |
|
* |
|
* Permission is hereby granted, free of charge, to any person obtaining |
|
* a copy of this software and associated documentation files (the |
|
* 'Software'), to deal in the Software without restriction, including |
|
* without limitation the rights to use, copy, modify, merge, publish, |
|
* distribute, sublicense, and/or sell copies of the Software, and to |
|
* permit persons to whom the Software is furnished to do so, subject to |
|
* the following conditions: |
|
* |
|
* The above copyright notice and this permission notice shall be |
|
* included in all copies or substantial portions of the Software. |
|
* |
|
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, |
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
|
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
|
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
// code copied and modified from escape-html |
|
/** |
|
* Module variables. |
|
* @private |
|
*/ |
|
|
|
var matchHtmlRegExp = /["'&<>]/; |
|
|
|
/** |
|
* Escape special characters in the given string of html. |
|
* |
|
* @param {string} string The string to escape for inserting into HTML |
|
* @return {string} |
|
* @public |
|
*/ |
|
|
|
function escapeHtml(string) { |
|
var str = '' + string; |
|
var match = matchHtmlRegExp.exec(str); |
|
|
|
if (!match) { |
|
return str; |
|
} |
|
|
|
var escape; |
|
var html = ''; |
|
var index = 0; |
|
var lastIndex = 0; |
|
|
|
for (index = match.index; index < str.length; index++) { |
|
switch (str.charCodeAt(index)) { |
|
case 34: |
|
// " |
|
escape = '"'; |
|
break; |
|
case 38: |
|
// & |
|
escape = '&'; |
|
break; |
|
case 39: |
|
// ' |
|
escape = '''; // modified from escape-html; used to be ''' |
|
break; |
|
case 60: |
|
// < |
|
escape = '<'; |
|
break; |
|
case 62: |
|
// > |
|
escape = '>'; |
|
break; |
|
default: |
|
continue; |
|
} |
|
|
|
if (lastIndex !== index) { |
|
html += str.substring(lastIndex, index); |
|
} |
|
|
|
lastIndex = index + 1; |
|
html += escape; |
|
} |
|
|
|
return lastIndex !== index ? html + str.substring(lastIndex, index) : html; |
|
} |
|
// end code copied and modified from escape-html |
|
|
|
|
|
/** |
|
* Escapes text to prevent scripting attacks. |
|
* |
|
* @param {*} text Text value to escape. |
|
* @return {string} An escaped string. |
|
*/ |
|
function escapeTextContentForBrowser(text) { |
|
if (typeof text === 'boolean' || typeof text === 'number') { |
|
// this shortcircuit helps perf for types that we know will never have |
|
// special characters, especially given that this function is used often |
|
// for numeric dom ids. |
|
return '' + text; |
|
} |
|
return escapeHtml(text); |
|
} |
|
|
|
module.exports = escapeTextContentForBrowser; |
|
},{}],108:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125); |
|
|
|
var ReactCurrentOwner = _dereq_(133); |
|
var ReactDOMComponentTree = _dereq_(34); |
|
var ReactInstanceMap = _dereq_(63); |
|
|
|
var getHostComponentFromComposite = _dereq_(115); |
|
var invariant = _dereq_(150); |
|
var warning = _dereq_(157); |
|
|
|
/** |
|
* Returns the DOM node rendered by this element. |
|
* |
|
* See https://facebook.github.io/react/docs/top-level-api.html#reactdom.finddomnode |
|
* |
|
* @param {ReactComponent|DOMElement} componentOrElement |
|
* @return {?DOMElement} The root node of this element. |
|
*/ |
|
function findDOMNode(componentOrElement) { |
|
if ("development" !== 'production') { |
|
var owner = ReactCurrentOwner.current; |
|
if (owner !== null) { |
|
"development" !== 'production' ? warning(owner._warnedAboutRefsInRender, '%s is accessing findDOMNode inside its render(). ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', owner.getName() || 'A component') : void 0; |
|
owner._warnedAboutRefsInRender = true; |
|
} |
|
} |
|
if (componentOrElement == null) { |
|
return null; |
|
} |
|
if (componentOrElement.nodeType === 1) { |
|
return componentOrElement; |
|
} |
|
|
|
var inst = ReactInstanceMap.get(componentOrElement); |
|
if (inst) { |
|
inst = getHostComponentFromComposite(inst); |
|
return inst ? ReactDOMComponentTree.getNodeFromInstance(inst) : null; |
|
} |
|
|
|
if (typeof componentOrElement.render === 'function') { |
|
!false ? "development" !== 'production' ? invariant(false, 'findDOMNode was called on an unmounted component.') : _prodInvariant('44') : void 0; |
|
} else { |
|
!false ? "development" !== 'production' ? invariant(false, 'Element appears to be neither ReactComponent nor DOMNode (keys: %s)', Object.keys(componentOrElement)) : _prodInvariant('45', Object.keys(componentOrElement)) : void 0; |
|
} |
|
} |
|
|
|
module.exports = findDOMNode; |
|
},{"115":115,"125":125,"133":133,"150":150,"157":157,"34":34,"63":63}],109:[function(_dereq_,module,exports){ |
|
(function (process){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var KeyEscapeUtils = _dereq_(23); |
|
var traverseAllChildren = _dereq_(130); |
|
var warning = _dereq_(157); |
|
|
|
var ReactComponentTreeHook; |
|
|
|
if (typeof process !== 'undefined' && process.env && "development" === 'test') { |
|
// Temporary hack. |
|
// Inline requires don't work well with Jest: |
|
// https://github.com/facebook/react/issues/7240 |
|
// Remove the inline requires when we don't need them anymore: |
|
// https://github.com/facebook/react/pull/7178 |
|
ReactComponentTreeHook = _dereq_(132); |
|
} |
|
|
|
/** |
|
* @param {function} traverseContext Context passed through traversal. |
|
* @param {?ReactComponent} child React child component. |
|
* @param {!string} name String name of key path to child. |
|
* @param {number=} selfDebugID Optional debugID of the current internal instance. |
|
*/ |
|
function flattenSingleChildIntoContext(traverseContext, child, name, selfDebugID) { |
|
// We found a component instance. |
|
if (traverseContext && typeof traverseContext === 'object') { |
|
var result = traverseContext; |
|
var keyUnique = result[name] === undefined; |
|
if ("development" !== 'production') { |
|
if (!ReactComponentTreeHook) { |
|
ReactComponentTreeHook = _dereq_(132); |
|
} |
|
if (!keyUnique) { |
|
"development" !== 'production' ? warning(false, 'flattenChildren(...): Encountered two children with the same key, ' + '`%s`. Child keys must be unique; when two children share a key, only ' + 'the first child will be used.%s', KeyEscapeUtils.unescape(name), ReactComponentTreeHook.getStackAddendumByID(selfDebugID)) : void 0; |
|
} |
|
} |
|
if (keyUnique && 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, selfDebugID) { |
|
if (children == null) { |
|
return children; |
|
} |
|
var result = {}; |
|
|
|
if ("development" !== 'production') { |
|
traverseAllChildren(children, function (traverseContext, child, name) { |
|
return flattenSingleChildIntoContext(traverseContext, child, name, selfDebugID); |
|
}, result); |
|
} else { |
|
traverseAllChildren(children, flattenSingleChildIntoContext, result); |
|
} |
|
return result; |
|
} |
|
|
|
module.exports = flattenChildren; |
|
}).call(this,undefined) |
|
},{"130":130,"132":132,"157":157,"23":23}],110:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
/** |
|
* @param {array} arr 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). |
|
*/ |
|
|
|
function forEachAccumulated(arr, cb, scope) { |
|
if (Array.isArray(arr)) { |
|
arr.forEach(cb, scope); |
|
} else if (arr) { |
|
cb.call(scope, arr); |
|
} |
|
} |
|
|
|
module.exports = forEachAccumulated; |
|
},{}],111:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
/** |
|
* `charCode` represents the actual "character code" and is safe to use with |
|
* `String.fromCharCode`. As such, only keys that correspond to printable |
|
* characters produce a valid `charCode`, the only exception to this is Enter. |
|
* The Tab-key is considered non-printable and does not have a `charCode`, |
|
* presumably because it does not produce a tab-character in browsers. |
|
* |
|
* @param {object} nativeEvent Native browser event. |
|
* @return {number} Normalized `charCode` property. |
|
*/ |
|
|
|
function getEventCharCode(nativeEvent) { |
|
var charCode; |
|
var keyCode = nativeEvent.keyCode; |
|
|
|
if ('charCode' in nativeEvent) { |
|
charCode = nativeEvent.charCode; |
|
|
|
// FF does not set `charCode` for the Enter-key, check against `keyCode`. |
|
if (charCode === 0 && keyCode === 13) { |
|
charCode = 13; |
|
} |
|
} else { |
|
// IE8 does not implement `charCode`, but `keyCode` has the correct value. |
|
charCode = keyCode; |
|
} |
|
|
|
// Some non-printable keys are reported in `charCode`/`keyCode`, discard them. |
|
// Must not discard the (non-)printable Enter-key. |
|
if (charCode >= 32 || charCode === 13) { |
|
return charCode; |
|
} |
|
|
|
return 0; |
|
} |
|
|
|
module.exports = getEventCharCode; |
|
},{}],112:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var getEventCharCode = _dereq_(111); |
|
|
|
/** |
|
* 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 `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) { |
|
if (nativeEvent.key) { |
|
// Normalize inconsistent values reported by browsers due to |
|
// implementations of a working draft specification. |
|
|
|
// FireFox implements `key` but returns `MozPrintableKey` for all |
|
// printable characters (normalized to `Unidentified`), ignore it. |
|
var key = normalizeKey[nativeEvent.key] || nativeEvent.key; |
|
if (key !== 'Unidentified') { |
|
return key; |
|
} |
|
} |
|
|
|
// Browser does not implement `key`, polyfill as much of it as we can. |
|
if (nativeEvent.type === 'keypress') { |
|
var charCode = getEventCharCode(nativeEvent); |
|
|
|
// The enter-key is technically both printable and non-printable and can |
|
// thus be captured by `keypress`, no other non-printable key should. |
|
return charCode === 13 ? 'Enter' : String.fromCharCode(charCode); |
|
} |
|
if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') { |
|
// While user keyboard layout determines the actual meaning of each |
|
// `keyCode` value, almost all function keys have a universal value. |
|
return translateToKey[nativeEvent.keyCode] || 'Unidentified'; |
|
} |
|
return ''; |
|
} |
|
|
|
module.exports = getEventKey; |
|
},{"111":111}],113:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
/** |
|
* Translation from modifier key to the associated property in the event. |
|
* @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers |
|
*/ |
|
|
|
var modifierKeyToProp = { |
|
'Alt': 'altKey', |
|
'Control': 'ctrlKey', |
|
'Meta': 'metaKey', |
|
'Shift': 'shiftKey' |
|
}; |
|
|
|
// IE8 does not implement getModifierState so we simply map it to the only |
|
// modifier keys exposed by the event itself, does not support Lock-keys. |
|
// Currently, all major browsers except Chrome seems to support Lock-keys. |
|
function modifierStateGetter(keyArg) { |
|
var syntheticEvent = this; |
|
var nativeEvent = syntheticEvent.nativeEvent; |
|
if (nativeEvent.getModifierState) { |
|
return nativeEvent.getModifierState(keyArg); |
|
} |
|
var keyProp = modifierKeyToProp[keyArg]; |
|
return keyProp ? !!nativeEvent[keyProp] : false; |
|
} |
|
|
|
function getEventModifierState(nativeEvent) { |
|
return modifierStateGetter; |
|
} |
|
|
|
module.exports = getEventModifierState; |
|
},{}],114:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'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; |
|
|
|
// Normalize SVG <use> element events #4963 |
|
if (target.correspondingUseElement) { |
|
target = target.correspondingUseElement; |
|
} |
|
|
|
// 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; |
|
},{}],115:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var ReactNodeTypes = _dereq_(69); |
|
|
|
function getHostComponentFromComposite(inst) { |
|
var type; |
|
|
|
while ((type = inst._renderedNodeType) === ReactNodeTypes.COMPOSITE) { |
|
inst = inst._renderedComponent; |
|
} |
|
|
|
if (type === ReactNodeTypes.HOST) { |
|
return inst._renderedComponent; |
|
} else if (type === ReactNodeTypes.EMPTY) { |
|
return null; |
|
} |
|
} |
|
|
|
module.exports = getHostComponentFromComposite; |
|
},{"69":69}],116:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
/* global Symbol */ |
|
|
|
var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; |
|
var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec. |
|
|
|
/** |
|
* Returns the iterator method function contained on the iterable object. |
|
* |
|
* Be sure to invoke the function with the iterable as context: |
|
* |
|
* var iteratorFn = getIteratorFn(myIterable); |
|
* if (iteratorFn) { |
|
* var iterator = iteratorFn.call(myIterable); |
|
* ... |
|
* } |
|
* |
|
* @param {?object} maybeIterable |
|
* @return {?function} |
|
*/ |
|
function getIteratorFn(maybeIterable) { |
|
var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]); |
|
if (typeof iteratorFn === 'function') { |
|
return iteratorFn; |
|
} |
|
} |
|
|
|
module.exports = getIteratorFn; |
|
},{}],117:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var nextDebugID = 1; |
|
|
|
function getNextDebugID() { |
|
return nextDebugID++; |
|
} |
|
|
|
module.exports = getNextDebugID; |
|
},{}],118:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'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; |
|
},{}],119:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var ExecutionEnvironment = _dereq_(136); |
|
|
|
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.documentElement ? 'textContent' : 'innerText'; |
|
} |
|
return contentKey; |
|
} |
|
|
|
module.exports = getTextContentAccessor; |
|
},{"136":136}],120:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var ExecutionEnvironment = _dereq_(136); |
|
|
|
/** |
|
* Generate a mapping of standard vendor prefixes using the defined style property and event name. |
|
* |
|
* @param {string} styleProp |
|
* @param {string} eventName |
|
* @returns {object} |
|
*/ |
|
function makePrefixMap(styleProp, eventName) { |
|
var prefixes = {}; |
|
|
|
prefixes[styleProp.toLowerCase()] = eventName.toLowerCase(); |
|
prefixes['Webkit' + styleProp] = 'webkit' + eventName; |
|
prefixes['Moz' + styleProp] = 'moz' + eventName; |
|
prefixes['ms' + styleProp] = 'MS' + eventName; |
|
prefixes['O' + styleProp] = 'o' + eventName.toLowerCase(); |
|
|
|
return prefixes; |
|
} |
|
|
|
/** |
|
* A list of event names to a configurable list of vendor prefixes. |
|
*/ |
|
var vendorPrefixes = { |
|
animationend: makePrefixMap('Animation', 'AnimationEnd'), |
|
animationiteration: makePrefixMap('Animation', 'AnimationIteration'), |
|
animationstart: makePrefixMap('Animation', 'AnimationStart'), |
|
transitionend: makePrefixMap('Transition', 'TransitionEnd') |
|
}; |
|
|
|
/** |
|
* Event names that have already been detected and prefixed (if applicable). |
|
*/ |
|
var prefixedEventNames = {}; |
|
|
|
/** |
|
* Element to check for prefixes on. |
|
*/ |
|
var style = {}; |
|
|
|
/** |
|
* Bootstrap if a DOM exists. |
|
*/ |
|
if (ExecutionEnvironment.canUseDOM) { |
|
style = document.createElement('div').style; |
|
|
|
// On some platforms, in particular some releases of Android 4.x, |
|
// the un-prefixed "animation" and "transition" properties are defined on the |
|
// style object but the events that fire will still be prefixed, so we need |
|
// to check if the un-prefixed events are usable, and if not remove them from the map. |
|
if (!('AnimationEvent' in window)) { |
|
delete vendorPrefixes.animationend.animation; |
|
delete vendorPrefixes.animationiteration.animation; |
|
delete vendorPrefixes.animationstart.animation; |
|
} |
|
|
|
// Same as above |
|
if (!('TransitionEvent' in window)) { |
|
delete vendorPrefixes.transitionend.transition; |
|
} |
|
} |
|
|
|
/** |
|
* Attempts to determine the correct vendor prefixed event name. |
|
* |
|
* @param {string} eventName |
|
* @returns {string} |
|
*/ |
|
function getVendorPrefixedEventName(eventName) { |
|
if (prefixedEventNames[eventName]) { |
|
return prefixedEventNames[eventName]; |
|
} else if (!vendorPrefixes[eventName]) { |
|
return eventName; |
|
} |
|
|
|
var prefixMap = vendorPrefixes[eventName]; |
|
|
|
for (var styleProp in prefixMap) { |
|
if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) { |
|
return prefixedEventNames[eventName] = prefixMap[styleProp]; |
|
} |
|
} |
|
|
|
return ''; |
|
} |
|
|
|
module.exports = getVendorPrefixedEventName; |
|
},{"136":136}],121:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125), |
|
_assign = _dereq_(158); |
|
|
|
var ReactCompositeComponent = _dereq_(30); |
|
var ReactEmptyComponent = _dereq_(54); |
|
var ReactHostComponent = _dereq_(59); |
|
|
|
var getNextDebugID = _dereq_(117); |
|
var invariant = _dereq_(150); |
|
var warning = _dereq_(157); |
|
|
|
// To avoid a cyclic dependency, we create the final class in this module |
|
var ReactCompositeComponentWrapper = function (element) { |
|
this.construct(element); |
|
}; |
|
_assign(ReactCompositeComponentWrapper.prototype, ReactCompositeComponent, { |
|
_instantiateReactComponent: instantiateReactComponent |
|
}); |
|
|
|
function getDeclarationErrorAddendum(owner) { |
|
if (owner) { |
|
var name = owner.getName(); |
|
if (name) { |
|
return ' Check the render method of `' + name + '`.'; |
|
} |
|
} |
|
return ''; |
|
} |
|
|
|
/** |
|
* Check if the type reference is a known internal type. I.e. not a user |
|
* provided composite type. |
|
* |
|
* @param {function} type |
|
* @return {boolean} Returns true if this is a valid internal type. |
|
*/ |
|
function isInternalComponentType(type) { |
|
return typeof type === 'function' && typeof type.prototype !== 'undefined' && typeof type.prototype.mountComponent === 'function' && typeof type.prototype.receiveComponent === 'function'; |
|
} |
|
|
|
/** |
|
* Given a ReactNode, create an instance that will actually be mounted. |
|
* |
|
* @param {ReactNode} node |
|
* @param {boolean} shouldHaveDebugID |
|
* @return {object} A new instance of the element's constructor. |
|
* @protected |
|
*/ |
|
function instantiateReactComponent(node, shouldHaveDebugID) { |
|
var instance; |
|
|
|
if (node === null || node === false) { |
|
instance = ReactEmptyComponent.create(instantiateReactComponent); |
|
} else if (typeof node === 'object') { |
|
var element = node; |
|
var type = element.type; |
|
if (typeof type !== 'function' && typeof type !== 'string') { |
|
var info = ''; |
|
if ("development" !== 'production') { |
|
if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) { |
|
info += ' You likely forgot to export your component from the file ' + 'it\'s defined in.'; |
|
} |
|
} |
|
info += getDeclarationErrorAddendum(element._owner); |
|
!false ? "development" !== 'production' ? invariant(false, 'Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s', type == null ? type : typeof type, info) : _prodInvariant('130', type == null ? type : typeof type, info) : void 0; |
|
} |
|
|
|
// Special case string values |
|
if (typeof element.type === 'string') { |
|
instance = ReactHostComponent.createInternalComponent(element); |
|
} else if (isInternalComponentType(element.type)) { |
|
// This is temporarily available for custom components that are not string |
|
// representations. I.e. ART. Once those are updated to use the string |
|
// representation, we can drop this code path. |
|
instance = new element.type(element); |
|
|
|
// We renamed this. Allow the old name for compat. :( |
|
if (!instance.getHostNode) { |
|
instance.getHostNode = instance.getNativeNode; |
|
} |
|
} else { |
|
instance = new ReactCompositeComponentWrapper(element); |
|
} |
|
} else if (typeof node === 'string' || typeof node === 'number') { |
|
instance = ReactHostComponent.createInstanceForText(node); |
|
} else { |
|
!false ? "development" !== 'production' ? invariant(false, 'Encountered invalid React node of type %s', typeof node) : _prodInvariant('131', typeof node) : void 0; |
|
} |
|
|
|
if ("development" !== 'production') { |
|
"development" !== 'production' ? warning(typeof instance.mountComponent === 'function' && typeof instance.receiveComponent === 'function' && typeof instance.getHostNode === 'function' && typeof instance.unmountComponent === 'function', 'Only React Components can be mounted.') : void 0; |
|
} |
|
|
|
// These two fields are used by the DOM and ART diffing algorithms |
|
// respectively. Instead of using expandos on components, we should be |
|
// storing the state needed by the diffing algorithms elsewhere. |
|
instance._mountIndex = 0; |
|
instance._mountImage = null; |
|
|
|
if ("development" !== 'production') { |
|
instance._debugID = shouldHaveDebugID ? getNextDebugID() : 0; |
|
} |
|
|
|
// Internal instances should fully constructed at this point, so they should |
|
// not get any new fields added to them at this point. |
|
if ("development" !== 'production') { |
|
if (Object.preventExtensions) { |
|
Object.preventExtensions(instance); |
|
} |
|
} |
|
|
|
return instance; |
|
} |
|
|
|
module.exports = instantiateReactComponent; |
|
},{"117":117,"125":125,"150":150,"157":157,"158":158,"30":30,"54":54,"59":59}],122:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var ExecutionEnvironment = _dereq_(136); |
|
|
|
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; |
|
},{"136":136}],123:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
'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) { |
|
var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase(); |
|
|
|
if (nodeName === 'input') { |
|
return !!supportedInputTypes[elem.type]; |
|
} |
|
|
|
if (nodeName === 'textarea') { |
|
return true; |
|
} |
|
|
|
return false; |
|
} |
|
|
|
module.exports = isTextInputElement; |
|
},{}],124:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var escapeTextContentForBrowser = _dereq_(107); |
|
|
|
/** |
|
* Escapes attribute value to prevent scripting attacks. |
|
* |
|
* @param {*} value Value to escape. |
|
* @return {string} An escaped string. |
|
*/ |
|
function quoteAttributeValueForBrowser(value) { |
|
return '"' + escapeTextContentForBrowser(value) + '"'; |
|
} |
|
|
|
module.exports = quoteAttributeValueForBrowser; |
|
},{"107":107}],125:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright (c) 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
'use strict'; |
|
|
|
/** |
|
* WARNING: DO NOT manually require this module. |
|
* This is a replacement for `invariant(...)` used by the error code system |
|
* and will _only_ be required by the corresponding babel pass. |
|
* It always throws. |
|
*/ |
|
|
|
function reactProdInvariant(code) { |
|
var argCount = arguments.length - 1; |
|
|
|
var message = 'Minified React error #' + code + '; visit ' + 'http://facebook.github.io/react/docs/error-decoder.html?invariant=' + code; |
|
|
|
for (var argIdx = 0; argIdx < argCount; argIdx++) { |
|
message += '&args[]=' + encodeURIComponent(arguments[argIdx + 1]); |
|
} |
|
|
|
message += ' for the full message or use the non-minified dev environment' + ' for full errors and additional helpful warnings.'; |
|
|
|
var error = new Error(message); |
|
error.name = 'Invariant Violation'; |
|
error.framesToPop = 1; // we don't care about reactProdInvariant's own frame |
|
|
|
throw error; |
|
} |
|
|
|
module.exports = reactProdInvariant; |
|
},{}],126:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var ReactMount = _dereq_(67); |
|
|
|
module.exports = ReactMount.renderSubtreeIntoContainer; |
|
},{"67":67}],127:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var ExecutionEnvironment = _dereq_(136); |
|
var DOMNamespaces = _dereq_(10); |
|
|
|
var WHITESPACE_TEST = /^[ \r\n\t\f]/; |
|
var NONVISIBLE_TEST = /<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/; |
|
|
|
var createMicrosoftUnsafeLocalFunction = _dereq_(105); |
|
|
|
// SVG temp container for IE lacking innerHTML |
|
var reusableSVGContainer; |
|
|
|
/** |
|
* Set the innerHTML property of a node, ensuring that whitespace is preserved |
|
* even in IE8. |
|
* |
|
* @param {DOMElement} node |
|
* @param {string} html |
|
* @internal |
|
*/ |
|
var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) { |
|
// IE does not have innerHTML for SVG nodes, so instead we inject the |
|
// new markup in a temp node and then move the child nodes across into |
|
// the target node |
|
if (node.namespaceURI === DOMNamespaces.svg && !('innerHTML' in node)) { |
|
reusableSVGContainer = reusableSVGContainer || document.createElement('div'); |
|
reusableSVGContainer.innerHTML = '<svg>' + html + '</svg>'; |
|
var svgNode = reusableSVGContainer.firstChild; |
|
while (svgNode.firstChild) { |
|
node.appendChild(svgNode.firstChild); |
|
} |
|
} else { |
|
node.innerHTML = html; |
|
} |
|
}); |
|
|
|
if (ExecutionEnvironment.canUseDOM) { |
|
// 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 |
|
|
|
// Feature detection; only IE8 is known to behave improperly like this. |
|
var testElement = document.createElement('div'); |
|
testElement.innerHTML = ' '; |
|
if (testElement.innerHTML === '') { |
|
setInnerHTML = function (node, html) { |
|
// 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. |
|
// TODO: What to do on a detached node? |
|
if (node.parentNode) { |
|
node.parentNode.replaceChild(node, node); |
|
} |
|
|
|
// We also implement a workaround for non-visible tags disappearing into |
|
// thin air on IE8, this only happens if there is no visible text |
|
// in-front of the non-visible tags. Piggyback on the whitespace fix |
|
// and simply check if any non-visible tags appear in the source. |
|
if (WHITESPACE_TEST.test(html) || html[0] === '<' && NONVISIBLE_TEST.test(html)) { |
|
// Recover leading whitespace by temporarily prepending any character. |
|
// \uFEFF has the potential advantage of being zero-width/invisible. |
|
// UglifyJS drops U+FEFF chars when parsing, so use String.fromCharCode |
|
// in hopes that this is preserved even if "\uFEFF" is transformed to |
|
// the actual Unicode character (by Babel, for example). |
|
// https://github.com/mishoo/UglifyJS2/blob/v2.4.20/lib/parse.js#L216 |
|
node.innerHTML = String.fromCharCode(0xFEFF) + html; |
|
|
|
// deleteData leaves an empty `TextNode` which offsets the index of all |
|
// children. Definitely want to avoid this. |
|
var textNode = node.firstChild; |
|
if (textNode.data.length === 1) { |
|
node.removeChild(textNode); |
|
} else { |
|
textNode.deleteData(0, 1); |
|
} |
|
} else { |
|
node.innerHTML = html; |
|
} |
|
}; |
|
} |
|
testElement = null; |
|
} |
|
|
|
module.exports = setInnerHTML; |
|
},{"10":10,"105":105,"136":136}],128:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var ExecutionEnvironment = _dereq_(136); |
|
var escapeTextContentForBrowser = _dereq_(107); |
|
var setInnerHTML = _dereq_(127); |
|
|
|
/** |
|
* Set the textContent property of a node, ensuring that whitespace is preserved |
|
* even in IE8. innerText is a poor substitute for textContent and, among many |
|
* issues, inserts <br> instead of the literal newline chars. innerHTML behaves |
|
* as it should. |
|
* |
|
* @param {DOMElement} node |
|
* @param {string} text |
|
* @internal |
|
*/ |
|
var setTextContent = function (node, text) { |
|
if (text) { |
|
var firstChild = node.firstChild; |
|
|
|
if (firstChild && firstChild === node.lastChild && firstChild.nodeType === 3) { |
|
firstChild.nodeValue = text; |
|
return; |
|
} |
|
} |
|
node.textContent = text; |
|
}; |
|
|
|
if (ExecutionEnvironment.canUseDOM) { |
|
if (!('textContent' in document.documentElement)) { |
|
setTextContent = function (node, text) { |
|
if (node.nodeType === 3) { |
|
node.nodeValue = text; |
|
return; |
|
} |
|
setInnerHTML(node, escapeTextContentForBrowser(text)); |
|
}; |
|
} |
|
} |
|
|
|
module.exports = setTextContent; |
|
},{"107":107,"127":127,"136":136}],129:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
/** |
|
* Given a `prevElement` and `nextElement`, determines if the existing |
|
* instance should be updated as opposed to being destroyed or replaced by a new |
|
* instance. Both arguments are elements. This ensures that this logic can |
|
* operate on stateless trees without any backing instance. |
|
* |
|
* @param {?object} prevElement |
|
* @param {?object} nextElement |
|
* @return {boolean} True if the existing instance should be updated. |
|
* @protected |
|
*/ |
|
|
|
function shouldUpdateReactComponent(prevElement, nextElement) { |
|
var prevEmpty = prevElement === null || prevElement === false; |
|
var nextEmpty = nextElement === null || nextElement === false; |
|
if (prevEmpty || nextEmpty) { |
|
return prevEmpty === nextEmpty; |
|
} |
|
|
|
var prevType = typeof prevElement; |
|
var nextType = typeof nextElement; |
|
if (prevType === 'string' || prevType === 'number') { |
|
return nextType === 'string' || nextType === 'number'; |
|
} else { |
|
return nextType === 'object' && prevElement.type === nextElement.type && prevElement.key === nextElement.key; |
|
} |
|
} |
|
|
|
module.exports = shouldUpdateReactComponent; |
|
},{}],130:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _prodInvariant = _dereq_(125); |
|
|
|
var ReactCurrentOwner = _dereq_(133); |
|
var REACT_ELEMENT_TYPE = _dereq_(53); |
|
|
|
var getIteratorFn = _dereq_(116); |
|
var invariant = _dereq_(150); |
|
var KeyEscapeUtils = _dereq_(23); |
|
var warning = _dereq_(157); |
|
|
|
var SEPARATOR = '.'; |
|
var SUBSEPARATOR = ':'; |
|
|
|
/** |
|
* This is inlined from ReactElement since this file is shared between |
|
* isomorphic and renderers. We could extract this to a |
|
* |
|
*/ |
|
|
|
/** |
|
* TODO: Test that a single child and an array with one item have the same key |
|
* pattern. |
|
*/ |
|
|
|
var didWarnAboutMaps = false; |
|
|
|
/** |
|
* 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) { |
|
// Do some typechecking here since we call this blindly. We want to ensure |
|
// that we don't block potential future ES APIs. |
|
if (component && typeof component === 'object' && component.key != null) { |
|
// Explicit key |
|
return KeyEscapeUtils.escape(component.key); |
|
} |
|
// Implicit key determined by the index in the set |
|
return index.toString(36); |
|
} |
|
|
|
/** |
|
* @param {?*} children Children tree container. |
|
* @param {!string} nameSoFar Name of the key path so far. |
|
* @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. |
|
*/ |
|
function traverseAllChildrenImpl(children, nameSoFar, callback, traverseContext) { |
|
var type = typeof children; |
|
|
|
if (type === 'undefined' || type === 'boolean') { |
|
// All of the above are perceived as null. |
|
children = null; |
|
} |
|
|
|
if (children === null || type === 'string' || type === 'number' || |
|
// The following is inlined from ReactElement. This means we can optimize |
|
// some checks. React Fiber also inlines this logic for similar purposes. |
|
type === 'object' && children.$$typeof === REACT_ELEMENT_TYPE) { |
|
callback(traverseContext, children, |
|
// 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. |
|
nameSoFar === '' ? SEPARATOR + getComponentKey(children, 0) : nameSoFar); |
|
return 1; |
|
} |
|
|
|
var child; |
|
var nextName; |
|
var subtreeCount = 0; // Count of children found in the current subtree. |
|
var nextNamePrefix = nameSoFar === '' ? SEPARATOR : nameSoFar + SUBSEPARATOR; |
|
|
|
if (Array.isArray(children)) { |
|
for (var i = 0; i < children.length; i++) { |
|
child = children[i]; |
|
nextName = nextNamePrefix + getComponentKey(child, i); |
|
subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext); |
|
} |
|
} else { |
|
var iteratorFn = getIteratorFn(children); |
|
if (iteratorFn) { |
|
var iterator = iteratorFn.call(children); |
|
var step; |
|
if (iteratorFn !== children.entries) { |
|
var ii = 0; |
|
while (!(step = iterator.next()).done) { |
|
child = step.value; |
|
nextName = nextNamePrefix + getComponentKey(child, ii++); |
|
subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext); |
|
} |
|
} else { |
|
if ("development" !== 'production') { |
|
var mapsAsChildrenAddendum = ''; |
|
if (ReactCurrentOwner.current) { |
|
var mapsAsChildrenOwnerName = ReactCurrentOwner.current.getName(); |
|
if (mapsAsChildrenOwnerName) { |
|
mapsAsChildrenAddendum = ' Check the render method of `' + mapsAsChildrenOwnerName + '`.'; |
|
} |
|
} |
|
"development" !== 'production' ? warning(didWarnAboutMaps, 'Using Maps as children is not yet fully supported. It is an ' + 'experimental feature that might be removed. Convert it to a ' + 'sequence / iterable of keyed ReactElements instead.%s', mapsAsChildrenAddendum) : void 0; |
|
didWarnAboutMaps = true; |
|
} |
|
// Iterator will provide entry [k,v] tuples rather than values. |
|
while (!(step = iterator.next()).done) { |
|
var entry = step.value; |
|
if (entry) { |
|
child = entry[1]; |
|
nextName = nextNamePrefix + KeyEscapeUtils.escape(entry[0]) + SUBSEPARATOR + getComponentKey(child, 0); |
|
subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext); |
|
} |
|
} |
|
} |
|
} else if (type === 'object') { |
|
var addendum = ''; |
|
if ("development" !== 'production') { |
|
addendum = ' If you meant to render a collection of children, use an array ' + 'instead or wrap the object using createFragment(object) from the ' + 'React add-ons.'; |
|
if (children._isReactElement) { |
|
addendum = ' It looks like you\'re using an element created by a different ' + 'version of React. Make sure to use only one copy of React.'; |
|
} |
|
if (ReactCurrentOwner.current) { |
|
var name = ReactCurrentOwner.current.getName(); |
|
if (name) { |
|
addendum += ' Check the render method of `' + name + '`.'; |
|
} |
|
} |
|
} |
|
var childrenString = String(children); |
|
!false ? "development" !== 'production' ? invariant(false, 'Objects are not valid as a React child (found: %s).%s', childrenString === '[object Object]' ? 'object with keys {' + Object.keys(children).join(', ') + '}' : childrenString, addendum) : _prodInvariant('31', childrenString === '[object Object]' ? 'object with keys {' + Object.keys(children).join(', ') + '}' : childrenString, addendum) : void 0; |
|
} |
|
} |
|
|
|
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. |
|
* @return {!number} The number of children in this subtree. |
|
*/ |
|
function traverseAllChildren(children, callback, traverseContext) { |
|
if (children == null) { |
|
return 0; |
|
} |
|
|
|
return traverseAllChildrenImpl(children, '', callback, traverseContext); |
|
} |
|
|
|
module.exports = traverseAllChildren; |
|
},{"116":116,"125":125,"133":133,"150":150,"157":157,"23":23,"53":53}],131:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2015-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var _assign = _dereq_(158); |
|
|
|
var emptyFunction = _dereq_(142); |
|
var warning = _dereq_(157); |
|
|
|
var validateDOMNesting = emptyFunction; |
|
|
|
if ("development" !== 'production') { |
|
// This validation code was written based on the HTML5 parsing spec: |
|
// https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope |
|
// |
|
// Note: this does not catch all invalid nesting, nor does it try to (as it's |
|
// not clear what practical benefit doing so provides); instead, we warn only |
|
// for cases where the parser will give a parse tree differing from what React |
|
// intended. For example, <b><div></div></b> is invalid but we don't warn |
|
// because it still parses correctly; we do warn for other cases like nested |
|
// <p> tags where the beginning of the second element implicitly closes the |
|
// first, causing a confusing mess. |
|
|
|
// https://html.spec.whatwg.org/multipage/syntax.html#special |
|
var specialTags = ['address', 'applet', 'area', 'article', 'aside', 'base', 'basefont', 'bgsound', 'blockquote', 'body', 'br', 'button', 'caption', 'center', 'col', 'colgroup', 'dd', 'details', 'dir', 'div', 'dl', 'dt', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'iframe', 'img', 'input', 'isindex', 'li', 'link', 'listing', 'main', 'marquee', 'menu', 'menuitem', 'meta', 'nav', 'noembed', 'noframes', 'noscript', 'object', 'ol', 'p', 'param', 'plaintext', 'pre', 'script', 'section', 'select', 'source', 'style', 'summary', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'track', 'ul', 'wbr', 'xmp']; |
|
|
|
// https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope |
|
var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template', |
|
|
|
// https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point |
|
// TODO: Distinguish by namespace here -- for <title>, including it here |
|
// errs on the side of fewer warnings |
|
'foreignObject', 'desc', 'title']; |
|
|
|
// https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope |
|
var buttonScopeTags = inScopeTags.concat(['button']); |
|
|
|
// https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags |
|
var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt']; |
|
|
|
var emptyAncestorInfo = { |
|
current: null, |
|
|
|
formTag: null, |
|
aTagInScope: null, |
|
buttonTagInScope: null, |
|
nobrTagInScope: null, |
|
pTagInButtonScope: null, |
|
|
|
listItemTagAutoclosing: null, |
|
dlItemTagAutoclosing: null |
|
}; |
|
|
|
var updatedAncestorInfo = function (oldInfo, tag, instance) { |
|
var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo); |
|
var info = { tag: tag, instance: instance }; |
|
|
|
if (inScopeTags.indexOf(tag) !== -1) { |
|
ancestorInfo.aTagInScope = null; |
|
ancestorInfo.buttonTagInScope = null; |
|
ancestorInfo.nobrTagInScope = null; |
|
} |
|
if (buttonScopeTags.indexOf(tag) !== -1) { |
|
ancestorInfo.pTagInButtonScope = null; |
|
} |
|
|
|
// See rules for 'li', 'dd', 'dt' start tags in |
|
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody |
|
if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') { |
|
ancestorInfo.listItemTagAutoclosing = null; |
|
ancestorInfo.dlItemTagAutoclosing = null; |
|
} |
|
|
|
ancestorInfo.current = info; |
|
|
|
if (tag === 'form') { |
|
ancestorInfo.formTag = info; |
|
} |
|
if (tag === 'a') { |
|
ancestorInfo.aTagInScope = info; |
|
} |
|
if (tag === 'button') { |
|
ancestorInfo.buttonTagInScope = info; |
|
} |
|
if (tag === 'nobr') { |
|
ancestorInfo.nobrTagInScope = info; |
|
} |
|
if (tag === 'p') { |
|
ancestorInfo.pTagInButtonScope = info; |
|
} |
|
if (tag === 'li') { |
|
ancestorInfo.listItemTagAutoclosing = info; |
|
} |
|
if (tag === 'dd' || tag === 'dt') { |
|
ancestorInfo.dlItemTagAutoclosing = info; |
|
} |
|
|
|
return ancestorInfo; |
|
}; |
|
|
|
/** |
|
* Returns whether |
|
*/ |
|
var isTagValidWithParent = function (tag, parentTag) { |
|
// First, let's check if we're in an unusual parsing mode... |
|
switch (parentTag) { |
|
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect |
|
case 'select': |
|
return tag === 'option' || tag === 'optgroup' || tag === '#text'; |
|
case 'optgroup': |
|
return tag === 'option' || tag === '#text'; |
|
// Strictly speaking, seeing an <option> doesn't mean we're in a <select> |
|
// but |
|
case 'option': |
|
return tag === '#text'; |
|
|
|
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd |
|
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption |
|
// No special behavior since these rules fall back to "in body" mode for |
|
// all except special table nodes which cause bad parsing behavior anyway. |
|
|
|
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr |
|
case 'tr': |
|
return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template'; |
|
|
|
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody |
|
case 'tbody': |
|
case 'thead': |
|
case 'tfoot': |
|
return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template'; |
|
|
|
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup |
|
case 'colgroup': |
|
return tag === 'col' || tag === 'template'; |
|
|
|
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable |
|
case 'table': |
|
return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template'; |
|
|
|
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead |
|
case 'head': |
|
return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template'; |
|
|
|
// https://html.spec.whatwg.org/multipage/semantics.html#the-html-element |
|
case 'html': |
|
return tag === 'head' || tag === 'body'; |
|
case '#document': |
|
return tag === 'html'; |
|
} |
|
|
|
// Probably in the "in body" parsing mode, so we outlaw only tag combos |
|
// where the parsing rules cause implicit opens or closes to be added. |
|
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody |
|
switch (tag) { |
|
case 'h1': |
|
case 'h2': |
|
case 'h3': |
|
case 'h4': |
|
case 'h5': |
|
case 'h6': |
|
return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6'; |
|
|
|
case 'rp': |
|
case 'rt': |
|
return impliedEndTags.indexOf(parentTag) === -1; |
|
|
|
case 'body': |
|
case 'caption': |
|
case 'col': |
|
case 'colgroup': |
|
case 'frame': |
|
case 'head': |
|
case 'html': |
|
case 'tbody': |
|
case 'td': |
|
case 'tfoot': |
|
case 'th': |
|
case 'thead': |
|
case 'tr': |
|
// These tags are only valid with a few parents that have special child |
|
// parsing rules -- if we're down here, then none of those matched and |
|
// so we allow it only if we don't know what the parent is, as all other |
|
// cases are invalid. |
|
return parentTag == null; |
|
} |
|
|
|
return true; |
|
}; |
|
|
|
/** |
|
* Returns whether |
|
*/ |
|
var findInvalidAncestorForTag = function (tag, ancestorInfo) { |
|
switch (tag) { |
|
case 'address': |
|
case 'article': |
|
case 'aside': |
|
case 'blockquote': |
|
case 'center': |
|
case 'details': |
|
case 'dialog': |
|
case 'dir': |
|
case 'div': |
|
case 'dl': |
|
case 'fieldset': |
|
case 'figcaption': |
|
case 'figure': |
|
case 'footer': |
|
case 'header': |
|
case 'hgroup': |
|
case 'main': |
|
case 'menu': |
|
case 'nav': |
|
case 'ol': |
|
case 'p': |
|
case 'section': |
|
case 'summary': |
|
case 'ul': |
|
|
|
case 'pre': |
|
case 'listing': |
|
|
|
case 'table': |
|
|
|
case 'hr': |
|
|
|
case 'xmp': |
|
|
|
case 'h1': |
|
case 'h2': |
|
case 'h3': |
|
case 'h4': |
|
case 'h5': |
|
case 'h6': |
|
return ancestorInfo.pTagInButtonScope; |
|
|
|
case 'form': |
|
return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope; |
|
|
|
case 'li': |
|
return ancestorInfo.listItemTagAutoclosing; |
|
|
|
case 'dd': |
|
case 'dt': |
|
return ancestorInfo.dlItemTagAutoclosing; |
|
|
|
case 'button': |
|
return ancestorInfo.buttonTagInScope; |
|
|
|
case 'a': |
|
// Spec says something about storing a list of markers, but it sounds |
|
// equivalent to this check. |
|
return ancestorInfo.aTagInScope; |
|
|
|
case 'nobr': |
|
return ancestorInfo.nobrTagInScope; |
|
} |
|
|
|
return null; |
|
}; |
|
|
|
/** |
|
* Given a ReactCompositeComponent instance, return a list of its recursive |
|
* owners, starting at the root and ending with the instance itself. |
|
*/ |
|
var findOwnerStack = function (instance) { |
|
if (!instance) { |
|
return []; |
|
} |
|
|
|
var stack = []; |
|
do { |
|
stack.push(instance); |
|
} while (instance = instance._currentElement._owner); |
|
stack.reverse(); |
|
return stack; |
|
}; |
|
|
|
var didWarn = {}; |
|
|
|
validateDOMNesting = function (childTag, childText, childInstance, ancestorInfo) { |
|
ancestorInfo = ancestorInfo || emptyAncestorInfo; |
|
var parentInfo = ancestorInfo.current; |
|
var parentTag = parentInfo && parentInfo.tag; |
|
|
|
if (childText != null) { |
|
"development" !== 'production' ? warning(childTag == null, 'validateDOMNesting: when childText is passed, childTag should be null') : void 0; |
|
childTag = '#text'; |
|
} |
|
|
|
var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo; |
|
var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo); |
|
var problematic = invalidParent || invalidAncestor; |
|
|
|
if (problematic) { |
|
var ancestorTag = problematic.tag; |
|
var ancestorInstance = problematic.instance; |
|
|
|
var childOwner = childInstance && childInstance._currentElement._owner; |
|
var ancestorOwner = ancestorInstance && ancestorInstance._currentElement._owner; |
|
|
|
var childOwners = findOwnerStack(childOwner); |
|
var ancestorOwners = findOwnerStack(ancestorOwner); |
|
|
|
var minStackLen = Math.min(childOwners.length, ancestorOwners.length); |
|
var i; |
|
|
|
var deepestCommon = -1; |
|
for (i = 0; i < minStackLen; i++) { |
|
if (childOwners[i] === ancestorOwners[i]) { |
|
deepestCommon = i; |
|
} else { |
|
break; |
|
} |
|
} |
|
|
|
var UNKNOWN = '(unknown)'; |
|
var childOwnerNames = childOwners.slice(deepestCommon + 1).map(function (inst) { |
|
return inst.getName() || UNKNOWN; |
|
}); |
|
var ancestorOwnerNames = ancestorOwners.slice(deepestCommon + 1).map(function (inst) { |
|
return inst.getName() || UNKNOWN; |
|
}); |
|
var ownerInfo = [].concat( |
|
// If the parent and child instances have a common owner ancestor, start |
|
// with that -- otherwise we just start with the parent's owners. |
|
deepestCommon !== -1 ? childOwners[deepestCommon].getName() || UNKNOWN : [], ancestorOwnerNames, ancestorTag, |
|
// If we're warning about an invalid (non-parent) ancestry, add '...' |
|
invalidAncestor ? ['...'] : [], childOwnerNames, childTag).join(' > '); |
|
|
|
var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + ownerInfo; |
|
if (didWarn[warnKey]) { |
|
return; |
|
} |
|
didWarn[warnKey] = true; |
|
|
|
var tagDisplayName = childTag; |
|
var whitespaceInfo = ''; |
|
if (childTag === '#text') { |
|
if (/\S/.test(childText)) { |
|
tagDisplayName = 'Text nodes'; |
|
} else { |
|
tagDisplayName = 'Whitespace text nodes'; |
|
whitespaceInfo = ' Make sure you don\'t have any extra whitespace between tags on ' + 'each line of your source code.'; |
|
} |
|
} else { |
|
tagDisplayName = '<' + childTag + '>'; |
|
} |
|
|
|
if (invalidParent) { |
|
var info = ''; |
|
if (ancestorTag === 'table' && childTag === 'tr') { |
|
info += ' Add a <tbody> to your code to match the DOM tree generated by ' + 'the browser.'; |
|
} |
|
"development" !== 'production' ? warning(false, 'validateDOMNesting(...): %s cannot appear as a child of <%s>.%s ' + 'See %s.%s', tagDisplayName, ancestorTag, whitespaceInfo, ownerInfo, info) : void 0; |
|
} else { |
|
"development" !== 'production' ? warning(false, 'validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>. See %s.', tagDisplayName, ancestorTag, ownerInfo) : void 0; |
|
} |
|
} |
|
}; |
|
|
|
validateDOMNesting.updatedAncestorInfo = updatedAncestorInfo; |
|
|
|
// For testing |
|
validateDOMNesting.isTagValidInContext = function (tag, ancestorInfo) { |
|
ancestorInfo = ancestorInfo || emptyAncestorInfo; |
|
var parentInfo = ancestorInfo.current; |
|
var parentTag = parentInfo && parentInfo.tag; |
|
return isTagValidWithParent(tag, parentTag) && !findInvalidAncestorForTag(tag, ancestorInfo); |
|
}; |
|
} |
|
|
|
module.exports = validateDOMNesting; |
|
},{"142":142,"157":157,"158":158}],132:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
/* globals React */ |
|
|
|
'use strict'; |
|
|
|
var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; |
|
|
|
module.exports = ReactInternals.ReactComponentTreeHook; |
|
},{}],133:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
/* globals React */ |
|
|
|
'use strict'; |
|
|
|
var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; |
|
|
|
module.exports = ReactInternals.ReactCurrentOwner; |
|
},{}],134:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
/* globals React */ |
|
|
|
'use strict'; |
|
|
|
module.exports = React; |
|
},{}],135:[function(_dereq_,module,exports){ |
|
'use strict'; |
|
|
|
/** |
|
* Copyright (c) 2013-present, Facebook, Inc. |
|
* |
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
* you may not use this file except in compliance with the License. |
|
* You may obtain a copy of the License at |
|
* |
|
* http://www.apache.org/licenses/LICENSE-2.0 |
|
* |
|
* Unless required by applicable law or agreed to in writing, software |
|
* distributed under the License is distributed on an "AS IS" BASIS, |
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
* See the License for the specific language governing permissions and |
|
* limitations under the License. |
|
* |
|
* @typechecks |
|
*/ |
|
|
|
var emptyFunction = _dereq_(142); |
|
|
|
/** |
|
* Upstream version of event listener. Does not take into account specific |
|
* nature of platform. |
|
*/ |
|
var EventListener = { |
|
/** |
|
* Listen to DOM events during the bubble phase. |
|
* |
|
* @param {DOMEventTarget} target DOM element to register listener on. |
|
* @param {string} eventType Event type, e.g. 'click' or 'mouseover'. |
|
* @param {function} callback Callback function. |
|
* @return {object} Object with a `remove` method. |
|
*/ |
|
listen: function listen(target, eventType, callback) { |
|
if (target.addEventListener) { |
|
target.addEventListener(eventType, callback, false); |
|
return { |
|
remove: function remove() { |
|
target.removeEventListener(eventType, callback, false); |
|
} |
|
}; |
|
} else if (target.attachEvent) { |
|
target.attachEvent('on' + eventType, callback); |
|
return { |
|
remove: function remove() { |
|
target.detachEvent('on' + eventType, callback); |
|
} |
|
}; |
|
} |
|
}, |
|
|
|
/** |
|
* Listen to DOM events during the capture phase. |
|
* |
|
* @param {DOMEventTarget} target DOM element to register listener on. |
|
* @param {string} eventType Event type, e.g. 'click' or 'mouseover'. |
|
* @param {function} callback Callback function. |
|
* @return {object} Object with a `remove` method. |
|
*/ |
|
capture: function capture(target, eventType, callback) { |
|
if (target.addEventListener) { |
|
target.addEventListener(eventType, callback, true); |
|
return { |
|
remove: function remove() { |
|
target.removeEventListener(eventType, callback, true); |
|
} |
|
}; |
|
} else { |
|
if ("development" !== 'production') { |
|
console.error('Attempted to listen to events during the capture phase on a ' + 'browser that does not support the capture phase. Your application ' + 'will not receive some events.'); |
|
} |
|
return { |
|
remove: emptyFunction |
|
}; |
|
} |
|
}, |
|
|
|
registerDefault: function registerDefault() {} |
|
}; |
|
|
|
module.exports = EventListener; |
|
},{"142":142}],136:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright (c) 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement); |
|
|
|
/** |
|
* Simple, lightweight module assisting with the detection and context of |
|
* Worker. Helps avoid circular dependencies and allows code to reason about |
|
* whether or not they are in a Worker, even if they never include the main |
|
* `ReactWorker` dependency. |
|
*/ |
|
var ExecutionEnvironment = { |
|
|
|
canUseDOM: canUseDOM, |
|
|
|
canUseWorkers: typeof Worker !== 'undefined', |
|
|
|
canUseEventListeners: canUseDOM && !!(window.addEventListener || window.attachEvent), |
|
|
|
canUseViewport: canUseDOM && !!window.screen, |
|
|
|
isInWorker: !canUseDOM // For now, this is true - might change in the future. |
|
|
|
}; |
|
|
|
module.exports = ExecutionEnvironment; |
|
},{}],137:[function(_dereq_,module,exports){ |
|
"use strict"; |
|
|
|
/** |
|
* Copyright (c) 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* @typechecks |
|
*/ |
|
|
|
var _hyphenPattern = /-(.)/g; |
|
|
|
/** |
|
* Camelcases a hyphenated string, for example: |
|
* |
|
* > camelize('background-color') |
|
* < "backgroundColor" |
|
* |
|
* @param {string} string |
|
* @return {string} |
|
*/ |
|
function camelize(string) { |
|
return string.replace(_hyphenPattern, function (_, character) { |
|
return character.toUpperCase(); |
|
}); |
|
} |
|
|
|
module.exports = camelize; |
|
},{}],138:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright (c) 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* @typechecks |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var camelize = _dereq_(137); |
|
|
|
var msPattern = /^-ms-/; |
|
|
|
/** |
|
* Camelcases a hyphenated CSS property name, for example: |
|
* |
|
* > camelizeStyleName('background-color') |
|
* < "backgroundColor" |
|
* > camelizeStyleName('-moz-transition') |
|
* < "MozTransition" |
|
* > camelizeStyleName('-ms-transition') |
|
* < "msTransition" |
|
* |
|
* As Andi Smith suggests |
|
* (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix |
|
* is converted to lowercase `ms`. |
|
* |
|
* @param {string} string |
|
* @return {string} |
|
*/ |
|
function camelizeStyleName(string) { |
|
return camelize(string.replace(msPattern, 'ms-')); |
|
} |
|
|
|
module.exports = camelizeStyleName; |
|
},{"137":137}],139:[function(_dereq_,module,exports){ |
|
'use strict'; |
|
|
|
/** |
|
* Copyright (c) 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
var isTextNode = _dereq_(152); |
|
|
|
/*eslint-disable no-bitwise */ |
|
|
|
/** |
|
* Checks if a given DOM node contains or is another DOM node. |
|
*/ |
|
function containsNode(outerNode, innerNode) { |
|
if (!outerNode || !innerNode) { |
|
return false; |
|
} else if (outerNode === innerNode) { |
|
return true; |
|
} else if (isTextNode(outerNode)) { |
|
return false; |
|
} else if (isTextNode(innerNode)) { |
|
return containsNode(outerNode, innerNode.parentNode); |
|
} else if ('contains' in outerNode) { |
|
return outerNode.contains(innerNode); |
|
} else if (outerNode.compareDocumentPosition) { |
|
return !!(outerNode.compareDocumentPosition(innerNode) & 16); |
|
} else { |
|
return false; |
|
} |
|
} |
|
|
|
module.exports = containsNode; |
|
},{"152":152}],140:[function(_dereq_,module,exports){ |
|
'use strict'; |
|
|
|
/** |
|
* Copyright (c) 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* @typechecks |
|
*/ |
|
|
|
var invariant = _dereq_(150); |
|
|
|
/** |
|
* Convert array-like objects to arrays. |
|
* |
|
* This API assumes the caller knows the contents of the data type. For less |
|
* well defined inputs use createArrayFromMixed. |
|
* |
|
* @param {object|function|filelist} obj |
|
* @return {array} |
|
*/ |
|
function toArray(obj) { |
|
var length = obj.length; |
|
|
|
// Some browsers builtin objects can report typeof 'function' (e.g. NodeList |
|
// in old versions of Safari). |
|
!(!Array.isArray(obj) && (typeof obj === 'object' || typeof obj === 'function')) ? "development" !== 'production' ? invariant(false, 'toArray: Array-like object expected') : invariant(false) : void 0; |
|
|
|
!(typeof length === 'number') ? "development" !== 'production' ? invariant(false, 'toArray: Object needs a length property') : invariant(false) : void 0; |
|
|
|
!(length === 0 || length - 1 in obj) ? "development" !== 'production' ? invariant(false, 'toArray: Object should have keys for indices') : invariant(false) : void 0; |
|
|
|
!(typeof obj.callee !== 'function') ? "development" !== 'production' ? invariant(false, 'toArray: Object can\'t be `arguments`. Use rest params ' + '(function(...args) {}) or Array.from() instead.') : invariant(false) : void 0; |
|
|
|
// Old IE doesn't give collections access to hasOwnProperty. Assume inputs |
|
// without method will throw during the slice call and skip straight to the |
|
// fallback. |
|
if (obj.hasOwnProperty) { |
|
try { |
|
return Array.prototype.slice.call(obj); |
|
} catch (e) { |
|
// IE < 9 does not support Array#slice on collections objects |
|
} |
|
} |
|
|
|
// Fall back to copying key by key. This assumes all keys have a value, |
|
// so will not preserve sparsely populated inputs. |
|
var ret = Array(length); |
|
for (var ii = 0; ii < length; ii++) { |
|
ret[ii] = obj[ii]; |
|
} |
|
return ret; |
|
} |
|
|
|
/** |
|
* Perform a heuristic test to determine if an object is "array-like". |
|
* |
|
* A monk asked Joshu, a Zen master, "Has a dog Buddha nature?" |
|
* Joshu replied: "Mu." |
|
* |
|
* This function determines if its argument has "array nature": it returns |
|
* true if the argument is an actual array, an `arguments' object, or an |
|
* HTMLCollection (e.g. node.childNodes or node.getElementsByTagName()). |
|
* |
|
* It will return false for other array-like objects like Filelist. |
|
* |
|
* @param {*} obj |
|
* @return {boolean} |
|
*/ |
|
function hasArrayNature(obj) { |
|
return ( |
|
// not null/false |
|
!!obj && ( |
|
// arrays are objects, NodeLists are functions in Safari |
|
typeof obj == 'object' || typeof obj == 'function') && |
|
// quacks like an array |
|
'length' in obj && |
|
// not window |
|
!('setInterval' in obj) && |
|
// no DOM node should be considered an array-like |
|
// a 'select' element has 'length' and 'item' properties on IE8 |
|
typeof obj.nodeType != 'number' && ( |
|
// a real array |
|
Array.isArray(obj) || |
|
// arguments |
|
'callee' in obj || |
|
// HTMLCollection/NodeList |
|
'item' in obj) |
|
); |
|
} |
|
|
|
/** |
|
* Ensure that the argument is an array by wrapping it in an array if it is not. |
|
* Creates a copy of the argument if it is already an array. |
|
* |
|
* This is mostly useful idiomatically: |
|
* |
|
* var createArrayFromMixed = require('createArrayFromMixed'); |
|
* |
|
* function takesOneOrMoreThings(things) { |
|
* things = createArrayFromMixed(things); |
|
* ... |
|
* } |
|
* |
|
* This allows you to treat `things' as an array, but accept scalars in the API. |
|
* |
|
* If you need to convert an array-like object, like `arguments`, into an array |
|
* use toArray instead. |
|
* |
|
* @param {*} obj |
|
* @return {array} |
|
*/ |
|
function createArrayFromMixed(obj) { |
|
if (!hasArrayNature(obj)) { |
|
return [obj]; |
|
} else if (Array.isArray(obj)) { |
|
return obj.slice(); |
|
} else { |
|
return toArray(obj); |
|
} |
|
} |
|
|
|
module.exports = createArrayFromMixed; |
|
},{"150":150}],141:[function(_dereq_,module,exports){ |
|
'use strict'; |
|
|
|
/** |
|
* Copyright (c) 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* @typechecks |
|
*/ |
|
|
|
/*eslint-disable fb-www/unsafe-html*/ |
|
|
|
var ExecutionEnvironment = _dereq_(136); |
|
|
|
var createArrayFromMixed = _dereq_(140); |
|
var getMarkupWrap = _dereq_(146); |
|
var invariant = _dereq_(150); |
|
|
|
/** |
|
* Dummy container used to render all markup. |
|
*/ |
|
var dummyNode = ExecutionEnvironment.canUseDOM ? document.createElement('div') : null; |
|
|
|
/** |
|
* Pattern used by `getNodeName`. |
|
*/ |
|
var nodeNamePattern = /^\s*<(\w+)/; |
|
|
|
/** |
|
* Extracts the `nodeName` of the first element in a string of markup. |
|
* |
|
* @param {string} markup String of markup. |
|
* @return {?string} Node name of the supplied markup. |
|
*/ |
|
function getNodeName(markup) { |
|
var nodeNameMatch = markup.match(nodeNamePattern); |
|
return nodeNameMatch && nodeNameMatch[1].toLowerCase(); |
|
} |
|
|
|
/** |
|
* Creates an array containing the nodes rendered from the supplied markup. The |
|
* optionally supplied `handleScript` function will be invoked once for each |
|
* <script> element that is rendered. If no `handleScript` function is supplied, |
|
* an exception is thrown if any <script> elements are rendered. |
|
* |
|
* @param {string} markup A string of valid HTML markup. |
|
* @param {?function} handleScript Invoked once for each rendered <script>. |
|
* @return {array<DOMElement|DOMTextNode>} An array of rendered nodes. |
|
*/ |
|
function createNodesFromMarkup(markup, handleScript) { |
|
var node = dummyNode; |
|
!!!dummyNode ? "development" !== 'production' ? invariant(false, 'createNodesFromMarkup dummy not initialized') : invariant(false) : void 0; |
|
var nodeName = getNodeName(markup); |
|
|
|
var wrap = nodeName && getMarkupWrap(nodeName); |
|
if (wrap) { |
|
node.innerHTML = wrap[1] + markup + wrap[2]; |
|
|
|
var wrapDepth = wrap[0]; |
|
while (wrapDepth--) { |
|
node = node.lastChild; |
|
} |
|
} else { |
|
node.innerHTML = markup; |
|
} |
|
|
|
var scripts = node.getElementsByTagName('script'); |
|
if (scripts.length) { |
|
!handleScript ? "development" !== 'production' ? invariant(false, 'createNodesFromMarkup(...): Unexpected <script> element rendered.') : invariant(false) : void 0; |
|
createArrayFromMixed(scripts).forEach(handleScript); |
|
} |
|
|
|
var nodes = Array.from(node.childNodes); |
|
while (node.lastChild) { |
|
node.removeChild(node.lastChild); |
|
} |
|
return nodes; |
|
} |
|
|
|
module.exports = createNodesFromMarkup; |
|
},{"136":136,"140":140,"146":146,"150":150}],142:[function(_dereq_,module,exports){ |
|
"use strict"; |
|
|
|
/** |
|
* Copyright (c) 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
*/ |
|
|
|
function makeEmptyFunction(arg) { |
|
return function () { |
|
return arg; |
|
}; |
|
} |
|
|
|
/** |
|
* This function accepts and discards inputs; it has no side effects. This is |
|
* primarily useful idiomatically for overridable function endpoints which |
|
* always need to be callable, since JS lacks a null-call idiom ala Cocoa. |
|
*/ |
|
var emptyFunction = function emptyFunction() {}; |
|
|
|
emptyFunction.thatReturns = makeEmptyFunction; |
|
emptyFunction.thatReturnsFalse = makeEmptyFunction(false); |
|
emptyFunction.thatReturnsTrue = makeEmptyFunction(true); |
|
emptyFunction.thatReturnsNull = makeEmptyFunction(null); |
|
emptyFunction.thatReturnsThis = function () { |
|
return this; |
|
}; |
|
emptyFunction.thatReturnsArgument = function (arg) { |
|
return arg; |
|
}; |
|
|
|
module.exports = emptyFunction; |
|
},{}],143:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright (c) 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var emptyObject = {}; |
|
|
|
if ("development" !== 'production') { |
|
Object.freeze(emptyObject); |
|
} |
|
|
|
module.exports = emptyObject; |
|
},{}],144:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright (c) 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
/** |
|
* @param {DOMElement} node input/textarea to focus |
|
*/ |
|
|
|
function focusNode(node) { |
|
// IE8 can throw "Can't move focus to the control because it is invisible, |
|
// not enabled, or of a type that does not accept the focus." for all kinds of |
|
// reasons that are too expensive and fragile to test. |
|
try { |
|
node.focus(); |
|
} catch (e) {} |
|
} |
|
|
|
module.exports = focusNode; |
|
},{}],145:[function(_dereq_,module,exports){ |
|
'use strict'; |
|
|
|
/** |
|
* Copyright (c) 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* @typechecks |
|
*/ |
|
|
|
/* eslint-disable fb-www/typeof-undefined */ |
|
|
|
/** |
|
* Same as document.activeElement but wraps in a try-catch block. In IE it is |
|
* not safe to call document.activeElement if there is nothing focused. |
|
* |
|
* The activeElement will be null only if the document or document body is not |
|
* yet defined. |
|
*/ |
|
function getActiveElement() /*?DOMElement*/{ |
|
if (typeof document === 'undefined') { |
|
return null; |
|
} |
|
try { |
|
return document.activeElement || document.body; |
|
} catch (e) { |
|
return document.body; |
|
} |
|
} |
|
|
|
module.exports = getActiveElement; |
|
},{}],146:[function(_dereq_,module,exports){ |
|
'use strict'; |
|
|
|
/** |
|
* Copyright (c) 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
/*eslint-disable fb-www/unsafe-html */ |
|
|
|
var ExecutionEnvironment = _dereq_(136); |
|
|
|
var invariant = _dereq_(150); |
|
|
|
/** |
|
* Dummy container used to detect which wraps are necessary. |
|
*/ |
|
var dummyNode = ExecutionEnvironment.canUseDOM ? document.createElement('div') : null; |
|
|
|
/** |
|
* Some browsers cannot use `innerHTML` to render certain elements standalone, |
|
* so we wrap them, render the wrapped nodes, then extract the desired node. |
|
* |
|
* In IE8, certain elements cannot render alone, so wrap all elements ('*'). |
|
*/ |
|
|
|
var shouldWrap = {}; |
|
|
|
var selectWrap = [1, '<select multiple="true">', '</select>']; |
|
var tableWrap = [1, '<table>', '</table>']; |
|
var trWrap = [3, '<table><tbody><tr>', '</tr></tbody></table>']; |
|
|
|
var svgWrap = [1, '<svg xmlns="http://www.w3.org/2000/svg">', '</svg>']; |
|
|
|
var markupWrap = { |
|
'*': [1, '?<div>', '</div>'], |
|
|
|
'area': [1, '<map>', '</map>'], |
|
'col': [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'], |
|
'legend': [1, '<fieldset>', '</fieldset>'], |
|
'param': [1, '<object>', '</object>'], |
|
'tr': [2, '<table><tbody>', '</tbody></table>'], |
|
|
|
'optgroup': selectWrap, |
|
'option': selectWrap, |
|
|
|
'caption': tableWrap, |
|
'colgroup': tableWrap, |
|
'tbody': tableWrap, |
|
'tfoot': tableWrap, |
|
'thead': tableWrap, |
|
|
|
'td': trWrap, |
|
'th': trWrap |
|
}; |
|
|
|
// Initialize the SVG elements since we know they'll always need to be wrapped |
|
// consistently. If they are created inside a <div> they will be initialized in |
|
// the wrong namespace (and will not display). |
|
var svgElements = ['circle', 'clipPath', 'defs', 'ellipse', 'g', 'image', 'line', 'linearGradient', 'mask', 'path', 'pattern', 'polygon', 'polyline', 'radialGradient', 'rect', 'stop', 'text', 'tspan']; |
|
svgElements.forEach(function (nodeName) { |
|
markupWrap[nodeName] = svgWrap; |
|
shouldWrap[nodeName] = true; |
|
}); |
|
|
|
/** |
|
* Gets the markup wrap configuration for the supplied `nodeName`. |
|
* |
|
* NOTE: This lazily detects which wraps are necessary for the current browser. |
|
* |
|
* @param {string} nodeName Lowercase `nodeName`. |
|
* @return {?array} Markup wrap configuration, if applicable. |
|
*/ |
|
function getMarkupWrap(nodeName) { |
|
!!!dummyNode ? "development" !== 'production' ? invariant(false, 'Markup wrapping node not initialized') : invariant(false) : void 0; |
|
if (!markupWrap.hasOwnProperty(nodeName)) { |
|
nodeName = '*'; |
|
} |
|
if (!shouldWrap.hasOwnProperty(nodeName)) { |
|
if (nodeName === '*') { |
|
dummyNode.innerHTML = '<link />'; |
|
} else { |
|
dummyNode.innerHTML = '<' + nodeName + '></' + nodeName + '>'; |
|
} |
|
shouldWrap[nodeName] = !dummyNode.firstChild; |
|
} |
|
return shouldWrap[nodeName] ? markupWrap[nodeName] : null; |
|
} |
|
|
|
module.exports = getMarkupWrap; |
|
},{"136":136,"150":150}],147:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright (c) 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* @typechecks |
|
*/ |
|
|
|
'use strict'; |
|
|
|
/** |
|
* Gets the scroll position of the supplied element or window. |
|
* |
|
* The return values are unbounded, unlike `getScrollPosition`. This means they |
|
* may be negative or exceed the element boundaries (which is possible using |
|
* inertial scrolling). |
|
* |
|
* @param {DOMWindow|DOMElement} scrollable |
|
* @return {object} Map with `x` and `y` keys. |
|
*/ |
|
|
|
function getUnboundedScrollPosition(scrollable) { |
|
if (scrollable === window) { |
|
return { |
|
x: window.pageXOffset || document.documentElement.scrollLeft, |
|
y: window.pageYOffset || document.documentElement.scrollTop |
|
}; |
|
} |
|
return { |
|
x: scrollable.scrollLeft, |
|
y: scrollable.scrollTop |
|
}; |
|
} |
|
|
|
module.exports = getUnboundedScrollPosition; |
|
},{}],148:[function(_dereq_,module,exports){ |
|
'use strict'; |
|
|
|
/** |
|
* Copyright (c) 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* @typechecks |
|
*/ |
|
|
|
var _uppercasePattern = /([A-Z])/g; |
|
|
|
/** |
|
* Hyphenates a camelcased string, for example: |
|
* |
|
* > hyphenate('backgroundColor') |
|
* < "background-color" |
|
* |
|
* For CSS style names, use `hyphenateStyleName` instead which works properly |
|
* with all vendor prefixes, including `ms`. |
|
* |
|
* @param {string} string |
|
* @return {string} |
|
*/ |
|
function hyphenate(string) { |
|
return string.replace(_uppercasePattern, '-$1').toLowerCase(); |
|
} |
|
|
|
module.exports = hyphenate; |
|
},{}],149:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright (c) 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* @typechecks |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var hyphenate = _dereq_(148); |
|
|
|
var msPattern = /^ms-/; |
|
|
|
/** |
|
* Hyphenates a camelcased CSS property name, for example: |
|
* |
|
* > hyphenateStyleName('backgroundColor') |
|
* < "background-color" |
|
* > hyphenateStyleName('MozTransition') |
|
* < "-moz-transition" |
|
* > hyphenateStyleName('msTransition') |
|
* < "-ms-transition" |
|
* |
|
* As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix |
|
* is converted to `-ms-`. |
|
* |
|
* @param {string} string |
|
* @return {string} |
|
*/ |
|
function hyphenateStyleName(string) { |
|
return hyphenate(string).replace(msPattern, '-ms-'); |
|
} |
|
|
|
module.exports = hyphenateStyleName; |
|
},{"148":148}],150:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright (c) 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
/** |
|
* Use invariant() to assert state which your program assumes to be true. |
|
* |
|
* Provide sprintf-style format (only %s is supported) and arguments |
|
* to provide information about what broke and what you were |
|
* expecting. |
|
* |
|
* The invariant message will be stripped in production, but the invariant |
|
* will remain to ensure logic does not differ in production. |
|
*/ |
|
|
|
var validateFormat = function validateFormat(format) {}; |
|
|
|
if ("development" !== 'production') { |
|
validateFormat = function validateFormat(format) { |
|
if (format === undefined) { |
|
throw new Error('invariant requires an error message argument'); |
|
} |
|
}; |
|
} |
|
|
|
function invariant(condition, format, a, b, c, d, e, f) { |
|
validateFormat(format); |
|
|
|
if (!condition) { |
|
var error; |
|
if (format === undefined) { |
|
error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.'); |
|
} else { |
|
var args = [a, b, c, d, e, f]; |
|
var argIndex = 0; |
|
error = new Error(format.replace(/%s/g, function () { |
|
return args[argIndex++]; |
|
})); |
|
error.name = 'Invariant Violation'; |
|
} |
|
|
|
error.framesToPop = 1; // we don't care about invariant's own frame |
|
throw error; |
|
} |
|
} |
|
|
|
module.exports = invariant; |
|
},{}],151:[function(_dereq_,module,exports){ |
|
'use strict'; |
|
|
|
/** |
|
* Copyright (c) 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* @typechecks |
|
*/ |
|
|
|
/** |
|
* @param {*} object The object to check. |
|
* @return {boolean} Whether or not the object is a DOM node. |
|
*/ |
|
function isNode(object) { |
|
return !!(object && (typeof Node === 'function' ? object instanceof Node : typeof object === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string')); |
|
} |
|
|
|
module.exports = isNode; |
|
},{}],152:[function(_dereq_,module,exports){ |
|
'use strict'; |
|
|
|
/** |
|
* Copyright (c) 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* @typechecks |
|
*/ |
|
|
|
var isNode = _dereq_(151); |
|
|
|
/** |
|
* @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; |
|
},{"151":151}],153:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright (c) 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* |
|
* @typechecks static-only |
|
*/ |
|
|
|
'use strict'; |
|
|
|
/** |
|
* Memoizes the return value of a function that accepts one string argument. |
|
*/ |
|
|
|
function memoizeStringOnly(callback) { |
|
var cache = {}; |
|
return function (string) { |
|
if (!cache.hasOwnProperty(string)) { |
|
cache[string] = callback.call(this, string); |
|
} |
|
return cache[string]; |
|
}; |
|
} |
|
|
|
module.exports = memoizeStringOnly; |
|
},{}],154:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright (c) 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* @typechecks |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var ExecutionEnvironment = _dereq_(136); |
|
|
|
var performance; |
|
|
|
if (ExecutionEnvironment.canUseDOM) { |
|
performance = window.performance || window.msPerformance || window.webkitPerformance; |
|
} |
|
|
|
module.exports = performance || {}; |
|
},{"136":136}],155:[function(_dereq_,module,exports){ |
|
'use strict'; |
|
|
|
/** |
|
* Copyright (c) 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* @typechecks |
|
*/ |
|
|
|
var performance = _dereq_(154); |
|
|
|
var performanceNow; |
|
|
|
/** |
|
* 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 |
|
* because of Facebook's testing infrastructure. |
|
*/ |
|
if (performance.now) { |
|
performanceNow = function performanceNow() { |
|
return performance.now(); |
|
}; |
|
} else { |
|
performanceNow = function performanceNow() { |
|
return Date.now(); |
|
}; |
|
} |
|
|
|
module.exports = performanceNow; |
|
},{"154":154}],156:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright (c) 2013-present, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
* @typechecks |
|
* |
|
*/ |
|
|
|
/*eslint-disable no-self-compare */ |
|
|
|
'use strict'; |
|
|
|
var hasOwnProperty = Object.prototype.hasOwnProperty; |
|
|
|
/** |
|
* inlined Object.is polyfill to avoid requiring consumers ship their own |
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is |
|
*/ |
|
function is(x, y) { |
|
// SameValue algorithm |
|
if (x === y) { |
|
// Steps 1-5, 7-10 |
|
// Steps 6.b-6.e: +0 != -0 |
|
// Added the nonzero y check to make Flow happy, but it is redundant |
|
return x !== 0 || y !== 0 || 1 / x === 1 / y; |
|
} else { |
|
// Step 6.a: NaN == NaN |
|
return x !== x && y !== y; |
|
} |
|
} |
|
|
|
/** |
|
* Performs equality by iterating through keys on an object and returning false |
|
* when any key has values which are not strictly equal between the arguments. |
|
* Returns true when the values of all keys are strictly equal. |
|
*/ |
|
function shallowEqual(objA, objB) { |
|
if (is(objA, objB)) { |
|
return true; |
|
} |
|
|
|
if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) { |
|
return false; |
|
} |
|
|
|
var keysA = Object.keys(objA); |
|
var keysB = Object.keys(objB); |
|
|
|
if (keysA.length !== keysB.length) { |
|
return false; |
|
} |
|
|
|
// Test for A's keys different from B. |
|
for (var i = 0; i < keysA.length; i++) { |
|
if (!hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) { |
|
return false; |
|
} |
|
} |
|
|
|
return true; |
|
} |
|
|
|
module.exports = shallowEqual; |
|
},{}],157:[function(_dereq_,module,exports){ |
|
/** |
|
* Copyright 2014-2015, Facebook, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the BSD-style license found in the |
|
* LICENSE file in the root directory of this source tree. An additional grant |
|
* of patent rights can be found in the PATENTS file in the same directory. |
|
* |
|
*/ |
|
|
|
'use strict'; |
|
|
|
var emptyFunction = _dereq_(142); |
|
|
|
/** |
|
* 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 ("development" !== 'production') { |
|
(function () { |
|
var printWarning = function printWarning(format) { |
|
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { |
|
args[_key - 1] = arguments[_key]; |
|
} |
|
|
|
var argIndex = 0; |
|
var message = 'Warning: ' + format.replace(/%s/g, function () { |
|
return args[argIndex++]; |
|
}); |
|
if (typeof console !== 'undefined') { |
|
console.error(message); |
|
} |
|
try { |
|
// --- Welcome to debugging React --- |
|
// This error was thrown as a convenience so that you can use this stack |
|
// to find the callsite that caused this warning to fire. |
|
throw new Error(message); |
|
} catch (x) {} |
|
}; |
|
|
|
warning = function warning(condition, format) { |
|
if (format === undefined) { |
|
throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument'); |
|
} |
|
|
|
if (format.indexOf('Failed Composite propType: ') === 0) { |
|
return; // Ignore CompositeComponent proptype check. |
|
} |
|
|
|
if (!condition) { |
|
for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { |
|
args[_key2 - 2] = arguments[_key2]; |
|
} |
|
|
|
printWarning.apply(undefined, [format].concat(args)); |
|
} |
|
}; |
|
})(); |
|
} |
|
|
|
module.exports = warning; |
|
},{"142":142}],158:[function(_dereq_,module,exports){ |
|
'use strict'; |
|
/* eslint-disable no-unused-vars */ |
|
var hasOwnProperty = Object.prototype.hasOwnProperty; |
|
var propIsEnumerable = Object.prototype.propertyIsEnumerable; |
|
|
|
function toObject(val) { |
|
if (val === null || val === undefined) { |
|
throw new TypeError('Object.assign cannot be called with null or undefined'); |
|
} |
|
|
|
return Object(val); |
|
} |
|
|
|
function shouldUseNative() { |
|
try { |
|
if (!Object.assign) { |
|
return false; |
|
} |
|
|
|
// Detect buggy property enumeration order in older V8 versions. |
|
|
|
// https://bugs.chromium.org/p/v8/issues/detail?id=4118 |
|
var test1 = new String('abc'); // eslint-disable-line |
|
test1[5] = 'de'; |
|
if (Object.getOwnPropertyNames(test1)[0] === '5') { |
|
return false; |
|
} |
|
|
|
// https://bugs.chromium.org/p/v8/issues/detail?id=3056 |
|
var test2 = {}; |
|
for (var i = 0; i < 10; i++) { |
|
test2['_' + String.fromCharCode(i)] = i; |
|
} |
|
var order2 = Object.getOwnPropertyNames(test2).map(function (n) { |
|
return test2[n]; |
|
}); |
|
if (order2.join('') !== '0123456789') { |
|
return false; |
|
} |
|
|
|
// https://bugs.chromium.org/p/v8/issues/detail?id=3056 |
|
var test3 = {}; |
|
'abcdefghijklmnopqrst'.split('').forEach(function (letter) { |
|
test3[letter] = letter; |
|
}); |
|
if (Object.keys(Object.assign({}, test3)).join('') !== |
|
'abcdefghijklmnopqrst') { |
|
return false; |
|
} |
|
|
|
return true; |
|
} catch (e) { |
|
// We don't expect any of the above to throw, but better to be safe. |
|
return false; |
|
} |
|
} |
|
|
|
module.exports = shouldUseNative() ? Object.assign : function (target, source) { |
|
var from; |
|
var to = toObject(target); |
|
var symbols; |
|
|
|
for (var s = 1; s < arguments.length; s++) { |
|
from = Object(arguments[s]); |
|
|
|
for (var key in from) { |
|
if (hasOwnProperty.call(from, key)) { |
|
to[key] = from[key]; |
|
} |
|
} |
|
|
|
if (Object.getOwnPropertySymbols) { |
|
symbols = Object.getOwnPropertySymbols(from); |
|
for (var i = 0; i < symbols.length; i++) { |
|
if (propIsEnumerable.call(from, symbols[i])) { |
|
to[symbols[i]] = from[symbols[i]]; |
|
} |
|
} |
|
} |
|
} |
|
|
|
return to; |
|
}; |
|
|
|
},{}]},{},[48])(48) |
|
}); |
|
}); |