b2128609ac
Preact (a minimalistic React alternative) had too many bugs ...
18526 lines
613 KiB
JavaScript
18526 lines
613 KiB
JavaScript
/**
|
|
* ReactDOM v16.0.0-alpha
|
|
*/
|
|
|
|
;(function(f) {
|
|
// CommonJS
|
|
if (typeof exports === "object" && typeof module !== "undefined") {
|
|
f(require('react'));
|
|
|
|
// RequireJS
|
|
} else if (typeof define === "function" && define.amd) {
|
|
require(['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;
|
|
}
|
|
f(g.React)
|
|
}
|
|
})(function(React) {
|
|
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.ReactDOM = 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_(35);
|
|
|
|
var focusNode = _dereq_(148);
|
|
|
|
var AutoFocusUtils = {
|
|
focusDOMComponent: function () {
|
|
focusNode(ReactDOMComponentTree.getNodeFromInstance(this));
|
|
}
|
|
};
|
|
|
|
module.exports = AutoFocusUtils;
|
|
},{"148":148,"35":35}],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_(140);
|
|
var FallbackCompositionState = _dereq_(21);
|
|
var SyntheticCompositionEvent = _dereq_(91);
|
|
var SyntheticInputEvent = _dereq_(95);
|
|
|
|
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;
|
|
},{"140":140,"20":20,"21":21,"91":91,"95":95}],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_(140);
|
|
var ReactInstrumentation = _dereq_(65);
|
|
|
|
var camelizeStyleName = _dereq_(142);
|
|
var dangerousStyleValue = _dereq_(108);
|
|
var getComponentName = _dereq_(113);
|
|
var hyphenateStyleName = _dereq_(153);
|
|
var memoizeStringOnly = _dereq_(157);
|
|
var warning = _dereq_(161);
|
|
|
|
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 = getComponentName(owner);
|
|
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;
|
|
},{"108":108,"113":113,"140":140,"142":142,"153":153,"157":157,"161":161,"4":4,"65":65}],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_(129);
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
var PooledClass = _dereq_(24);
|
|
|
|
var invariant = _dereq_(154);
|
|
|
|
/**
|
|
* 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);
|
|
},{"129":129,"154":154,"24":24}],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_(140);
|
|
var ReactControlledComponent = _dereq_(30);
|
|
var ReactDOMComponentTree = _dereq_(35);
|
|
var ReactGenericBatching = _dereq_(60);
|
|
var SyntheticEvent = _dereq_(93);
|
|
|
|
var inputValueTracking = _dereq_(124);
|
|
var getEventTarget = _dereq_(117);
|
|
var isEventSupported = _dereq_(126);
|
|
var isTextInputElement = _dereq_(127);
|
|
|
|
var eventTypes = {
|
|
change: {
|
|
phasedRegistrationNames: {
|
|
bubbled: 'onChange',
|
|
captured: 'onChangeCapture'
|
|
},
|
|
dependencies: ['topBlur', 'topChange', 'topClick', 'topFocus', 'topInput', 'topKeyDown', 'topKeyUp', 'topSelectionChange']
|
|
}
|
|
};
|
|
|
|
function createAndAccumulateChangeEvent(inst, nativeEvent, target) {
|
|
var event = SyntheticEvent.getPooled(eventTypes.change, inst, nativeEvent, target);
|
|
event.type = 'change';
|
|
// Flag this event loop as needing state restore.
|
|
ReactControlledComponent.enqueueStateRestore(inst);
|
|
EventPropagators.accumulateTwoPhaseDispatches(event);
|
|
return event;
|
|
}
|
|
/**
|
|
* For IE shims
|
|
*/
|
|
var activeElement = null;
|
|
var activeElementInst = 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 = createAndAccumulateChangeEvent(activeElementInst, nativeEvent, getEventTarget(nativeEvent));
|
|
|
|
// 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.
|
|
ReactGenericBatching.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 getInstIfValueChanged(targetInst) {
|
|
if (inputValueTracking.updateValueIfChanged(targetInst)) {
|
|
return targetInst;
|
|
}
|
|
}
|
|
|
|
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.
|
|
isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9);
|
|
}
|
|
|
|
/**
|
|
* (For IE <=9) 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;
|
|
activeElement.attachEvent('onpropertychange', handlePropertyChange);
|
|
}
|
|
|
|
/**
|
|
* (For IE <=9) Removes the event listeners from the currently-tracked element,
|
|
* if any exists.
|
|
*/
|
|
function stopWatchingForValueChange() {
|
|
if (!activeElement) {
|
|
return;
|
|
}
|
|
activeElement.detachEvent('onpropertychange', handlePropertyChange);
|
|
activeElement = null;
|
|
activeElementInst = null;
|
|
}
|
|
|
|
/**
|
|
* (For IE <=9) 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;
|
|
}
|
|
if (getInstIfValueChanged(activeElementInst)) {
|
|
manualDispatchChangeEvent(nativeEvent);
|
|
}
|
|
}
|
|
|
|
function handleEventsForInputEventPolyfill(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, 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 getTargetInstForInputEventPolyfill(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.
|
|
return getInstIfValueChanged(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.
|
|
var nodeName = elem.nodeName;
|
|
return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio');
|
|
}
|
|
|
|
function getTargetInstForClickEvent(topLevelType, targetInst) {
|
|
if (topLevelType === 'topClick') {
|
|
return getInstIfValueChanged(targetInst);
|
|
}
|
|
}
|
|
|
|
function getTargetInstForInputOrChangeEvent(topLevelType, targetInst) {
|
|
if (topLevelType === 'topInput' || topLevelType === 'topChange') {
|
|
return getInstIfValueChanged(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,
|
|
|
|
_isInputEventSupported: isInputEventSupported,
|
|
|
|
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 = getTargetInstForInputOrChangeEvent;
|
|
} else {
|
|
getTargetInstFunc = getTargetInstForInputEventPolyfill;
|
|
handleEventFunc = handleEventsForInputEventPolyfill;
|
|
}
|
|
} else if (shouldUseClickEvent(targetNode)) {
|
|
getTargetInstFunc = getTargetInstForClickEvent;
|
|
}
|
|
|
|
if (getTargetInstFunc) {
|
|
var inst = getTargetInstFunc(topLevelType, targetInst);
|
|
if (inst) {
|
|
var event = createAndAccumulateChangeEvent(inst, nativeEvent, nativeEventTarget);
|
|
return event;
|
|
}
|
|
}
|
|
|
|
if (handleEventFunc) {
|
|
handleEventFunc(topLevelType, targetNode, targetInst);
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = ChangeEventPlugin;
|
|
},{"117":117,"124":124,"126":126,"127":127,"140":140,"17":17,"20":20,"30":30,"35":35,"60":60,"93":93}],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_(10);
|
|
var Danger = _dereq_(14);
|
|
var ReactDOMComponentTree = _dereq_(35);
|
|
var ReactInstrumentation = _dereq_(65);
|
|
|
|
var createMicrosoftUnsafeLocalFunction = _dereq_(107);
|
|
var setInnerHTML = _dereq_(131);
|
|
var setTextContent = _dereq_(132);
|
|
|
|
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;
|
|
},{"10":10,"107":107,"131":131,"132":132,"14":14,"35":35,"65":65}],9:[function(_dereq_,module,exports){
|
|
/**
|
|
* Copyright 2013-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
*/
|
|
|
|
'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 DOMEventPluginOrder = ['ResponderEventPlugin', 'SimpleEventPlugin', 'TapEventPlugin', 'EnterLeaveEventPlugin', 'ChangeEventPlugin', 'SelectEventPlugin', 'BeforeInputEventPlugin'];
|
|
|
|
module.exports = DOMEventPluginOrder;
|
|
},{}],10:[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_(11);
|
|
var setInnerHTML = _dereq_(131);
|
|
|
|
var createMicrosoftUnsafeLocalFunction = _dereq_(107);
|
|
var setTextContent = _dereq_(132);
|
|
|
|
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;
|
|
},{"107":107,"11":11,"131":131,"132":132}],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 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;
|
|
},{}],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 _prodInvariant = _dereq_(129);
|
|
|
|
var invariant = _dereq_(154);
|
|
|
|
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;
|
|
},{"129":129,"154":154}],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 DOMProperty = _dereq_(12);
|
|
var ReactDOMComponentTree = _dereq_(35);
|
|
var ReactInstrumentation = _dereq_(65);
|
|
|
|
var quoteAttributeValueForBrowser = _dereq_(128);
|
|
var warning = _dereq_(161);
|
|
|
|
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;
|
|
},{"12":12,"128":128,"161":161,"35":35,"65":65}],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';
|
|
|
|
var _prodInvariant = _dereq_(129);
|
|
|
|
var DOMLazyTree = _dereq_(10);
|
|
var ExecutionEnvironment = _dereq_(140);
|
|
|
|
var createNodesFromMarkup = _dereq_(145);
|
|
var emptyFunction = _dereq_(146);
|
|
var invariant = _dereq_(154);
|
|
|
|
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;
|
|
},{"10":10,"129":129,"140":140,"145":145,"146":146,"154":154}],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_(35);
|
|
var SyntheticMouseEvent = _dereq_(97);
|
|
|
|
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,"35":35,"97":97}],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_(129);
|
|
|
|
var EventPluginRegistry = _dereq_(18);
|
|
var EventPluginUtils = _dereq_(19);
|
|
var ReactErrorUtils = _dereq_(56);
|
|
|
|
var accumulateInto = _dereq_(104);
|
|
var forEachAccumulated = _dereq_(112);
|
|
var invariant = _dereq_(154);
|
|
|
|
/**
|
|
* 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;
|
|
};
|
|
|
|
/**
|
|
* 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) {
|
|
var bankForRegistrationName = listenerBank[registrationName];
|
|
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;
|
|
},{"104":104,"112":112,"129":129,"154":154,"18":18,"19":19,"56":56}],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_(129);
|
|
|
|
var invariant = _dereq_(154);
|
|
|
|
/**
|
|
* 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;
|
|
},{"129":129,"154":154}],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_(129);
|
|
|
|
var ReactTreeTraversal = _dereq_(81);
|
|
var ReactErrorUtils = _dereq_(56);
|
|
|
|
var invariant = _dereq_(154);
|
|
var warning = _dereq_(161);
|
|
|
|
/**
|
|
* Injected dependencies:
|
|
*/
|
|
|
|
/**
|
|
* - `ComponentTree`: [required] Module that can convert between React instances
|
|
* and actual node references.
|
|
*/
|
|
var ComponentTree;
|
|
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;
|
|
}
|
|
}
|
|
};
|
|
|
|
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 ReactTreeTraversal.isAncestor(a, b);
|
|
},
|
|
getLowestCommonAncestor: function (a, b) {
|
|
return ReactTreeTraversal.getLowestCommonAncestor(a, b);
|
|
},
|
|
getParentInstance: function (inst) {
|
|
return ReactTreeTraversal.getParentInstance(inst);
|
|
},
|
|
traverseTwoPhase: function (target, fn, arg) {
|
|
return ReactTreeTraversal.traverseTwoPhase(target, fn, arg);
|
|
},
|
|
traverseEnterLeave: function (from, to, fn, argFrom, argTo) {
|
|
return ReactTreeTraversal.traverseEnterLeave(from, to, fn, argFrom, argTo);
|
|
},
|
|
|
|
injection: injection
|
|
};
|
|
|
|
module.exports = EventPluginUtils;
|
|
},{"129":129,"154":154,"161":161,"56":56,"81":81}],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_(104);
|
|
var forEachAccumulated = _dereq_(112);
|
|
var warning = _dereq_(161);
|
|
|
|
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;
|
|
},{"104":104,"112":112,"161":161,"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_(162);
|
|
|
|
var PooledClass = _dereq_(24);
|
|
|
|
var getTextContentAccessor = _dereq_(122);
|
|
|
|
/**
|
|
* 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;
|
|
},{"122":122,"162":162,"24":24}],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_(12);
|
|
|
|
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,
|
|
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,
|
|
// support for projecting regular DOM Elements via V1 named slots ( shadow dom )
|
|
slot: 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;
|
|
},{"12":12}],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_(129);
|
|
|
|
var invariant = _dereq_(154);
|
|
|
|
/**
|
|
* 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 fiveArgumentPooler = function (a1, a2, a3, a4, a5) {
|
|
var Klass = this;
|
|
if (Klass.instancePool.length) {
|
|
var instance = Klass.instancePool.pop();
|
|
Klass.call(instance, a1, a2, a3, a4, a5);
|
|
return instance;
|
|
} else {
|
|
return new Klass(a1, a2, a3, a4, a5);
|
|
}
|
|
};
|
|
|
|
var standardReleaser = function (instance) {
|
|
var Klass = this;
|
|
!(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,
|
|
fiveArgumentPooler: fiveArgumentPooler
|
|
};
|
|
|
|
module.exports = PooledClass;
|
|
},{"129":129,"154":154}],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 _assign = _dereq_(162);
|
|
|
|
var EventPluginRegistry = _dereq_(18);
|
|
var ReactEventEmitterMixin = _dereq_(57);
|
|
var ViewportMetrics = _dereq_(103);
|
|
|
|
var getVendorPrefixedEventName = _dereq_(123);
|
|
var isEventSupported = _dereq_(126);
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
}
|
|
},
|
|
|
|
isListeningToAllDependencies: function (registrationName, mountAt) {
|
|
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])) {
|
|
return false;
|
|
}
|
|
}
|
|
return 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;
|
|
},{"103":103,"123":123,"126":126,"162":162,"18":18,"57":57}],26:[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_(125);
|
|
var KeyEscapeUtils = _dereq_(23);
|
|
var shouldUpdateReactComponent = _dereq_(133);
|
|
var traverseAllChildren = _dereq_(134);
|
|
var warning = _dereq_(161);
|
|
|
|
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_(136);
|
|
}
|
|
|
|
function instantiateChild(childInstances, child, name, selfDebugID) {
|
|
// We found a component instance.
|
|
var keyUnique = childInstances[name] === undefined;
|
|
if ("development" !== 'production') {
|
|
if (!ReactComponentTreeHook) {
|
|
ReactComponentTreeHook = _dereq_(136);
|
|
}
|
|
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, /* safely */
|
|
false /* skipLifecycle */
|
|
);
|
|
}
|
|
// 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, /* safely */
|
|
false /* skipLifecycle */
|
|
);
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 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, skipLifecycle) {
|
|
for (var name in renderedChildren) {
|
|
if (renderedChildren.hasOwnProperty(name)) {
|
|
var renderedChild = renderedChildren[name];
|
|
ReactReconciler.unmountComponent(renderedChild, safely, skipLifecycle);
|
|
}
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = ReactChildReconciler;
|
|
}).call(this,undefined)
|
|
},{"125":125,"133":133,"134":134,"136":136,"161":161,"23":23,"75":75}],27:[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_(39);
|
|
|
|
/**
|
|
* 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;
|
|
},{"39":39,"8":8}],28:[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_(129);
|
|
|
|
var invariant = _dereq_(154);
|
|
|
|
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;
|
|
},{"129":129,"154":154}],29:[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_(129),
|
|
_assign = _dereq_(162);
|
|
|
|
var React = _dereq_(138);
|
|
var ReactComponentEnvironment = _dereq_(28);
|
|
var ReactCurrentOwner = _dereq_(137);
|
|
var ReactErrorUtils = _dereq_(56);
|
|
var ReactInstanceMap = _dereq_(64);
|
|
var ReactInstrumentation = _dereq_(65);
|
|
var ReactNodeTypes = _dereq_(70);
|
|
var ReactReconciler = _dereq_(75);
|
|
|
|
if ("development" !== 'production') {
|
|
var checkReactTypeSpec = _dereq_(106);
|
|
}
|
|
|
|
var emptyObject = _dereq_(147);
|
|
var invariant = _dereq_(154);
|
|
var shallowEqual = _dereq_(160);
|
|
var shouldUpdateReactComponent = _dereq_(133);
|
|
var warning = _dereq_(161);
|
|
|
|
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, '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;
|
|
|
|
if (inst.componentWillMount) {
|
|
if ("development" !== 'production') {
|
|
measureLifeCyclePerf(function () {
|
|
return inst.componentWillMount();
|
|
}, this._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);
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
// setState callbacks during willMount should end up here
|
|
var callbacks = this._pendingCallbacks;
|
|
if (callbacks) {
|
|
this._pendingCallbacks = null;
|
|
for (var i = 0; i < callbacks.length; i++) {
|
|
transaction.getReactMountReady().enqueue(callbacks[i], 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, /* safely */
|
|
// Don't call componentWillUnmount() because they never fully mounted:
|
|
true /* skipLifecyle */
|
|
);
|
|
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) {
|
|
// 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 debugID = 0;
|
|
if ("development" !== 'production') {
|
|
debugID = this._debugID;
|
|
}
|
|
|
|
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, skipLifecycle) {
|
|
if (!this._renderedComponent) {
|
|
return;
|
|
}
|
|
|
|
var inst = this._instance;
|
|
|
|
if (inst.componentWillUnmount && !inst._calledComponentWillUnmount) {
|
|
inst._calledComponentWillUnmount = true;
|
|
|
|
if (safely) {
|
|
if (!skipLifecycle) {
|
|
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, skipLifecycle);
|
|
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;
|
|
|
|
if (inst.unstable_handleError) {
|
|
this._updateRenderedComponentWithErrorHandling(transaction, unmaskedContext);
|
|
} else {
|
|
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
|
|
*/
|
|
_updateRenderedComponentWithErrorHandling: function (transaction, context) {
|
|
var checkpoint = transaction.checkpoint();
|
|
try {
|
|
this._updateRenderedComponent(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();
|
|
|
|
// Gracefully update to a clean state
|
|
this._updateRenderedComponentWithNextElement(transaction, context, null, true /* safely */
|
|
);
|
|
|
|
// 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).
|
|
this._updateRenderedComponent(transaction, context);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Call the component's `render` method and update the DOM accordingly.
|
|
*
|
|
* @param {ReactReconcileTransaction} transaction
|
|
* @internal
|
|
*/
|
|
_updateRenderedComponent: function (transaction, context) {
|
|
var nextRenderedElement = this._renderValidatedComponent();
|
|
this._updateRenderedComponentWithNextElement(transaction, context, nextRenderedElement, false /* safely */
|
|
);
|
|
},
|
|
|
|
/**
|
|
* Call the component's `render` method and update the DOM accordingly.
|
|
*
|
|
* @param {ReactReconcileTransaction} transaction
|
|
* @internal
|
|
*/
|
|
_updateRenderedComponentWithNextElement: function (transaction, context, nextRenderedElement, safely) {
|
|
var prevComponentInstance = this._renderedComponent;
|
|
var prevRenderedElement = prevComponentInstance._currentElement;
|
|
|
|
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, safely, false /* skipLifecycle */
|
|
);
|
|
|
|
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;
|
|
},{"106":106,"129":129,"133":133,"137":137,"138":138,"147":147,"154":154,"160":160,"161":161,"162":162,"28":28,"56":56,"64":64,"65":65,"70":70,"75":75}],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_(129);
|
|
|
|
var invariant = _dereq_(154);
|
|
|
|
// Use to restore controlled state after a change event has fired.
|
|
|
|
var fiberHostComponent = null;
|
|
|
|
var ReactControlledComponentInjection = {
|
|
injectFiberControlledHostComponent: function (hostComponentImpl) {
|
|
// The fiber implementation doesn't use dynamic dispatch so we need to
|
|
// inject the implementation.
|
|
fiberHostComponent = hostComponentImpl;
|
|
}
|
|
};
|
|
|
|
var restoreTarget = null;
|
|
var restoreQueue = null;
|
|
|
|
function restoreStateOfTarget(internalInstance) {
|
|
if (typeof internalInstance.tag === 'number') {
|
|
!(fiberHostComponent && typeof fiberHostComponent.restoreControlledState === 'function') ? "development" !== 'production' ? invariant(false, 'Fiber needs to be injected to handle a fiber target for controlled events.') : _prodInvariant('146') : void 0;
|
|
fiberHostComponent.restoreControlledState(internalInstance);
|
|
}
|
|
!(typeof internalInstance.restoreControlledState === 'function') ? "development" !== 'production' ? invariant(false, 'The internal instance must be a React host component.') : _prodInvariant('147') : void 0;
|
|
// If it is not a Fiber, we can just use dynamic dispatch.
|
|
internalInstance.restoreControlledState();
|
|
}
|
|
|
|
var ReactControlledComponent = {
|
|
injection: ReactControlledComponentInjection,
|
|
|
|
enqueueStateRestore: function (target) {
|
|
if (restoreTarget) {
|
|
if (restoreQueue) {
|
|
restoreQueue.push(target);
|
|
} else {
|
|
restoreQueue = [target];
|
|
}
|
|
} else {
|
|
restoreTarget = target;
|
|
}
|
|
},
|
|
restoreStateIfNeeded: function () {
|
|
if (!restoreTarget) {
|
|
return;
|
|
}
|
|
var target = restoreTarget;
|
|
var queuedTargets = restoreQueue;
|
|
restoreTarget = null;
|
|
restoreQueue = null;
|
|
|
|
restoreStateOfTarget(target);
|
|
if (queuedTargets) {
|
|
for (var i = 0; i < queuedTargets.length; i++) {
|
|
restoreStateOfTarget(queuedTargets[i]);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
module.exports = ReactControlledComponent;
|
|
},{"129":129,"154":154}],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.
|
|
*
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var React = _dereq_(138);
|
|
|
|
var getComponentName = _dereq_(113);
|
|
var warning = _dereq_(161);
|
|
|
|
var hasReadOnlyValue = {
|
|
'button': true,
|
|
'checkbox': true,
|
|
'image': true,
|
|
'hidden': true,
|
|
'radio': true,
|
|
'reset': true,
|
|
'submit': true
|
|
};
|
|
|
|
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 = getComponentName(owner);
|
|
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 ReactControlledValuePropTypes = {
|
|
checkPropTypes: function (tagName, props, owner) {
|
|
for (var propName in propTypes) {
|
|
if (propTypes.hasOwnProperty(propName)) {
|
|
var error = propTypes[propName](props, propName, tagName, 'prop');
|
|
}
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
module.exports = ReactControlledValuePropTypes;
|
|
},{"113":113,"138":138,"161":161}],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.
|
|
*
|
|
*/
|
|
|
|
/* globals __REACT_DEVTOOLS_GLOBAL_HOOK__*/
|
|
|
|
'use strict';
|
|
|
|
var ReactDOMComponentTree = _dereq_(35);
|
|
var ReactDOMInjection = _dereq_(40);
|
|
var ReactDOMStackInjection = _dereq_(47);
|
|
var ReactMount = _dereq_(68);
|
|
var ReactReconciler = _dereq_(75);
|
|
var ReactUpdates = _dereq_(84);
|
|
var ReactVersion = _dereq_(85);
|
|
|
|
var findDOMNode = _dereq_(110);
|
|
var getHostComponentFromComposite = _dereq_(118);
|
|
var renderSubtreeIntoContainer = _dereq_(130);
|
|
var warning = _dereq_(161);
|
|
|
|
ReactDOMInjection.inject();
|
|
ReactDOMStackInjection.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.
|
|
/* eslint-enable camelcase */
|
|
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_(140);
|
|
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_(65);
|
|
var ReactDOMUnknownPropertyHook = _dereq_(51);
|
|
var ReactDOMNullInputValuePropHook = _dereq_(43);
|
|
var ReactDOMInvalidARIAHook = _dereq_(42);
|
|
|
|
ReactInstrumentation.debugTool.addHook(ReactDOMUnknownPropertyHook);
|
|
ReactInstrumentation.debugTool.addHook(ReactDOMNullInputValuePropHook);
|
|
ReactInstrumentation.debugTool.addHook(ReactDOMInvalidARIAHook);
|
|
}
|
|
|
|
module.exports = ReactDOM;
|
|
},{"110":110,"118":118,"130":130,"140":140,"161":161,"35":35,"40":40,"42":42,"43":43,"47":47,"51":51,"65":65,"68":68,"75":75,"84":84,"85":85}],33:[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_(129),
|
|
_assign = _dereq_(162);
|
|
|
|
var AutoFocusUtils = _dereq_(2);
|
|
var CSSPropertyOperations = _dereq_(5);
|
|
var DOMLazyTree = _dereq_(10);
|
|
var DOMNamespaces = _dereq_(11);
|
|
var DOMProperty = _dereq_(12);
|
|
var DOMPropertyOperations = _dereq_(13);
|
|
var EventPluginHub = _dereq_(17);
|
|
var EventPluginRegistry = _dereq_(18);
|
|
var ReactBrowserEventEmitter = _dereq_(25);
|
|
var ReactDOMComponentFlags = _dereq_(34);
|
|
var ReactDOMComponentTree = _dereq_(35);
|
|
var ReactDOMInput = _dereq_(41);
|
|
var ReactDOMOption = _dereq_(44);
|
|
var ReactDOMSelect = _dereq_(45);
|
|
var ReactDOMTextarea = _dereq_(49);
|
|
var ReactInstrumentation = _dereq_(65);
|
|
var ReactMultiChild = _dereq_(69);
|
|
var ReactServerRenderingTransaction = _dereq_(77);
|
|
|
|
var emptyFunction = _dereq_(146);
|
|
var escapeTextContentForBrowser = _dereq_(109);
|
|
var invariant = _dereq_(154);
|
|
var isEventSupported = _dereq_(126);
|
|
var shallowEqual = _dereq_(160);
|
|
var inputValueTracking = _dereq_(124);
|
|
var validateDOMNesting = _dereq_(135);
|
|
var warning = _dereq_(161);
|
|
var didWarnShadyDOM = false;
|
|
|
|
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
|
|
});
|
|
}
|
|
|
|
// TODO: This is coming from future #8192. Dedupe this and enqueuePutListener.
|
|
function ensureListeningTo(inst, registrationName, 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);
|
|
}
|
|
|
|
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 trackInputValue() {
|
|
inputValueTracking.track(this);
|
|
}
|
|
|
|
function trapClickOnNonInteractiveElement() {
|
|
// 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
|
|
// Just set it using the onclick property so that we don't have to manage any
|
|
// bookkeeping for it. Not sure if we need to clear it when the listener is
|
|
// removed.
|
|
// TODO: Only do this for the relevant Safaris maybe?
|
|
var node = getNode(this);
|
|
node.onclick = emptyFunction;
|
|
}
|
|
|
|
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
|
|
};
|
|
|
|
// NOTE: menuitem's close tag should be omitted, but that causes problems.
|
|
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(trackInputValue, this);
|
|
transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this);
|
|
// For controlled components we always need to ensure we're listening
|
|
// to onChange. Even if there is no listener.
|
|
ensureListeningTo(this, 'onChange', transaction);
|
|
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);
|
|
// For controlled components we always need to ensure we're listening
|
|
// to onChange. Even if there is no listener.
|
|
ensureListeningTo(this, 'onChange', transaction);
|
|
break;
|
|
case 'textarea':
|
|
ReactDOMTextarea.mountWrapper(this, props, hostParent);
|
|
props = ReactDOMTextarea.getHostProps(this, props);
|
|
transaction.getReactMountReady().enqueue(trackInputValue, this);
|
|
transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this);
|
|
// For controlled components we always need to ensure we're listening
|
|
// to onChange. Even if there is no listener.
|
|
ensureListeningTo(this, 'onChange', transaction);
|
|
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;
|
|
var type = this._currentElement.type;
|
|
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');
|
|
div.innerHTML = '<' + type + '></' + type + '>';
|
|
el = div.removeChild(div.firstChild);
|
|
} else if (props.is) {
|
|
el = ownerDocument.createElement(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(type);
|
|
}
|
|
} else {
|
|
el = ownerDocument.createElementNS(namespaceURI, type);
|
|
}
|
|
var isCustomComponentTag = isCustomComponent(this._tag, props);
|
|
if ("development" !== 'production' && isCustomComponentTag && !didWarnShadyDOM && el.shadyRoot) {
|
|
var owner = this._currentElement._owner;
|
|
var name = owner && owner.getName() || 'A component';
|
|
"development" !== 'production' ? warning(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', name) : void 0;
|
|
didWarnShadyDOM = true;
|
|
}
|
|
ReactDOMComponentTree.precacheNode(this, el);
|
|
this._flags |= Flags.hasCachedChildNodes;
|
|
if (!this._hostParent) {
|
|
DOMPropertyOperations.setAttributeForRoot(el);
|
|
}
|
|
this._updateDOMProperties(null, props, transaction, isCustomComponentTag);
|
|
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 + '</' + 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;
|
|
default:
|
|
if (typeof props.onClick === 'function') {
|
|
transaction.getReactMountReady().enqueue(trapClickOnNonInteractiveElement, 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;
|
|
default:
|
|
if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') {
|
|
transaction.getReactMountReady().enqueue(trapClickOnNonInteractiveElement, this);
|
|
}
|
|
break;
|
|
}
|
|
|
|
assertValidProps(this, nextProps);
|
|
var isCustomComponentTag = isCustomComponent(this._tag, nextProps);
|
|
this._updateDOMProperties(lastProps, nextProps, transaction, isCustomComponentTag);
|
|
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, isCustomComponentTag) {
|
|
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 (isCustomComponentTag) {
|
|
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, skipLifecycle) {
|
|
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 'input':
|
|
case 'textarea':
|
|
inputValueTracking.stopTracking(this);
|
|
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, skipLifecycle);
|
|
ReactDOMComponentTree.uncacheNode(this);
|
|
EventPluginHub.deleteAllListeners(this);
|
|
this._rootNodeID = 0;
|
|
this._domID = 0;
|
|
this._wrapperState = null;
|
|
|
|
if ("development" !== 'production') {
|
|
setAndValidateContentChildDev.call(this, null);
|
|
}
|
|
},
|
|
|
|
restoreControlledState: function () {
|
|
switch (this._tag) {
|
|
case 'input':
|
|
ReactDOMInput.restoreControlledState(this);
|
|
return;
|
|
case 'textarea':
|
|
ReactDOMTextarea.restoreControlledState(this);
|
|
return;
|
|
case 'select':
|
|
ReactDOMSelect.restoreControlledState(this);
|
|
return;
|
|
}
|
|
},
|
|
|
|
getPublicInstance: function () {
|
|
return getNode(this);
|
|
}
|
|
|
|
};
|
|
|
|
_assign(ReactDOMComponent.prototype, ReactDOMComponent.Mixin, ReactMultiChild);
|
|
|
|
module.exports = ReactDOMComponent;
|
|
},{"10":10,"109":109,"11":11,"12":12,"124":124,"126":126,"129":129,"13":13,"135":135,"146":146,"154":154,"160":160,"161":161,"162":162,"17":17,"18":18,"2":2,"25":25,"34":34,"35":35,"41":41,"44":44,"45":45,"49":49,"5":5,"65":65,"69":69,"77":77}],34:[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;
|
|
},{}],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 _prodInvariant = _dereq_(129);
|
|
|
|
var DOMProperty = _dereq_(12);
|
|
var ReactDOMComponentFlags = _dereq_(34);
|
|
|
|
var invariant = _dereq_(154);
|
|
|
|
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;
|
|
},{"12":12,"129":129,"154":154,"34":34}],36:[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_(135);
|
|
|
|
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;
|
|
},{"135":135}],37:[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_(162);
|
|
|
|
var DOMLazyTree = _dereq_(10);
|
|
var ReactDOMComponentTree = _dereq_(35);
|
|
|
|
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;
|
|
},{"10":10,"162":162,"35":35}],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 ReactDOMFeatureFlags = {
|
|
useCreateElement: true,
|
|
useFiber: false
|
|
};
|
|
|
|
module.exports = ReactDOMFeatureFlags;
|
|
},{}],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 DOMChildrenOperations = _dereq_(8);
|
|
var ReactDOMComponentTree = _dereq_(35);
|
|
|
|
/**
|
|
* 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;
|
|
},{"35":35,"8":8}],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 ARIADOMPropertyConfig = _dereq_(1);
|
|
var BeforeInputEventPlugin = _dereq_(3);
|
|
var DOMProperty = _dereq_(12);
|
|
var ChangeEventPlugin = _dereq_(7);
|
|
var DOMEventPluginOrder = _dereq_(9);
|
|
var EnterLeaveEventPlugin = _dereq_(15);
|
|
var EventPluginHub = _dereq_(17);
|
|
var EventPluginUtils = _dereq_(19);
|
|
var HTMLDOMPropertyConfig = _dereq_(22);
|
|
var ReactBrowserEventEmitter = _dereq_(25);
|
|
var ReactDOMComponentTree = _dereq_(35);
|
|
var ReactEventListener = _dereq_(58);
|
|
var SVGDOMPropertyConfig = _dereq_(86);
|
|
var SelectEventPlugin = _dereq_(87);
|
|
var SimpleEventPlugin = _dereq_(88);
|
|
|
|
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;
|
|
|
|
ReactBrowserEventEmitter.injection.injectReactEventListener(ReactEventListener);
|
|
|
|
/**
|
|
* Inject modules for resolving DOM hierarchy and plugin ordering.
|
|
*/
|
|
EventPluginHub.injection.injectEventPluginOrder(DOMEventPluginOrder);
|
|
EventPluginUtils.injection.injectComponentTree(ReactDOMComponentTree);
|
|
|
|
/**
|
|
* Some important event plugins included by default (without having to require
|
|
* them).
|
|
*/
|
|
EventPluginHub.injection.injectEventPluginsByName({
|
|
SimpleEventPlugin: SimpleEventPlugin,
|
|
EnterLeaveEventPlugin: EnterLeaveEventPlugin,
|
|
ChangeEventPlugin: ChangeEventPlugin,
|
|
SelectEventPlugin: SelectEventPlugin,
|
|
BeforeInputEventPlugin: BeforeInputEventPlugin
|
|
});
|
|
|
|
DOMProperty.injection.injectDOMPropertyConfig(ARIADOMPropertyConfig);
|
|
DOMProperty.injection.injectDOMPropertyConfig(HTMLDOMPropertyConfig);
|
|
DOMProperty.injection.injectDOMPropertyConfig(SVGDOMPropertyConfig);
|
|
}
|
|
|
|
module.exports = {
|
|
inject: inject
|
|
};
|
|
},{"1":1,"12":12,"15":15,"17":17,"19":19,"22":22,"25":25,"3":3,"35":35,"58":58,"7":7,"86":86,"87":87,"88":88,"9":9}],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 _prodInvariant = _dereq_(129),
|
|
_assign = _dereq_(162);
|
|
|
|
var DOMPropertyOperations = _dereq_(13);
|
|
var ReactControlledValuePropTypes = _dereq_(31);
|
|
var ReactDOMComponentTree = _dereq_(35);
|
|
|
|
var invariant = _dereq_(154);
|
|
var warning = _dereq_(161);
|
|
|
|
var didWarnValueDefaultValue = false;
|
|
var didWarnCheckedDefaultChecked = false;
|
|
var didWarnControlledToUncontrolled = false;
|
|
var didWarnUncontrolledToControlled = false;
|
|
|
|
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 = props.value;
|
|
var checked = props.checked;
|
|
|
|
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
|
|
});
|
|
|
|
return hostProps;
|
|
},
|
|
|
|
mountWrapper: function (inst, props) {
|
|
if ("development" !== 'production') {
|
|
ReactControlledValuePropTypes.checkPropTypes('input', props, inst._currentElement._owner);
|
|
|
|
var owner = inst._currentElement._owner;
|
|
|
|
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
|
|
};
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
var checked = props.checked;
|
|
if (checked != null) {
|
|
DOMPropertyOperations.setValueForProperty(ReactDOMComponentTree.getNodeFromInstance(inst), 'checked', checked || false);
|
|
}
|
|
|
|
var node = ReactDOMComponentTree.getNodeFromInstance(inst);
|
|
var value = props.value;
|
|
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;
|
|
}
|
|
},
|
|
|
|
restoreControlledState: function (inst) {
|
|
if (inst._rootNodeID) {
|
|
// DOM component is still mounted; update
|
|
ReactDOMInput.updateWrapper(inst);
|
|
}
|
|
var props = inst._currentElement.props;
|
|
updateNamedCousins(inst, props);
|
|
}
|
|
};
|
|
|
|
function updateNamedCousins(thisInstance, props) {
|
|
var name = props.name;
|
|
if (props.type === 'radio' && name != null) {
|
|
var rootNode = ReactDOMComponentTree.getNodeFromInstance(thisInstance);
|
|
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. It might not even be in the
|
|
// document. Let's just use the local `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.
|
|
if (otherInstance._rootNodeID) {
|
|
ReactDOMInput.updateWrapper(otherInstance);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = ReactDOMInput;
|
|
},{"129":129,"13":13,"154":154,"161":161,"162":162,"31":31,"35":35}],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 DOMProperty = _dereq_(12);
|
|
var ReactComponentTreeHook = _dereq_(136);
|
|
|
|
var warning = _dereq_(161);
|
|
|
|
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;
|
|
},{"12":12,"136":136,"161":161}],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 ReactComponentTreeHook = _dereq_(136);
|
|
|
|
var warning = _dereq_(161);
|
|
|
|
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;
|
|
},{"136":136,"161":161}],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 _assign = _dereq_(162);
|
|
|
|
var React = _dereq_(138);
|
|
var ReactDOMComponentTree = _dereq_(35);
|
|
var ReactDOMSelect = _dereq_(45);
|
|
|
|
var warning = _dereq_(161);
|
|
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;
|
|
},{"138":138,"161":161,"162":162,"35":35,"45":45}],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 _assign = _dereq_(162);
|
|
|
|
var ReactControlledValuePropTypes = _dereq_(31);
|
|
var ReactDOMComponentTree = _dereq_(35);
|
|
|
|
var warning = _dereq_(161);
|
|
|
|
var didWarnValueDefaultValue = false;
|
|
|
|
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;
|
|
ReactControlledValuePropTypes.checkPropTypes('select', props, owner);
|
|
|
|
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 options = ReactDOMComponentTree.getNodeFromInstance(inst).options;
|
|
|
|
if (multiple) {
|
|
var selectedValue = {};
|
|
for (var i = 0; i < propValue.length; i++) {
|
|
selectedValue['' + propValue[i]] = true;
|
|
}
|
|
for (var _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.
|
|
var _selectedValue = '' + propValue;
|
|
for (var _i2 = 0; _i2 < options.length; _i2++) {
|
|
if (options[_i2].value === _selectedValue) {
|
|
options[_i2].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, {
|
|
value: undefined
|
|
});
|
|
},
|
|
|
|
mountWrapper: function (inst, props) {
|
|
if ("development" !== 'production') {
|
|
checkSelectPropTypes(inst, props);
|
|
}
|
|
|
|
var value = props.value;
|
|
inst._wrapperState = {
|
|
initialValue: value != null ? value : props.defaultValue,
|
|
listeners: null,
|
|
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 = props.value;
|
|
if (value != null) {
|
|
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 ? [] : '');
|
|
}
|
|
}
|
|
},
|
|
|
|
restoreControlledState: function (inst) {
|
|
if (inst._rootNodeID) {
|
|
var props = inst._currentElement.props;
|
|
var value = props.value;
|
|
|
|
if (value != null) {
|
|
updateOptions(inst, Boolean(props.multiple), value);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
module.exports = ReactDOMSelect;
|
|
},{"161":161,"162":162,"31":31,"35":35}],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 ExecutionEnvironment = _dereq_(140);
|
|
|
|
var getNodeForCharacterOffset = _dereq_(121);
|
|
var getTextContentAccessor = _dereq_(122);
|
|
|
|
/**
|
|
* 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;
|
|
},{"121":121,"122":122,"140":140}],47:[function(_dereq_,module,exports){
|
|
/**
|
|
* Copyright 2013-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* 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 ReactComponentEnvironment = _dereq_(28);
|
|
var ReactComponentBrowserEnvironment = _dereq_(27);
|
|
var ReactDOMComponent = _dereq_(33);
|
|
var ReactDOMEmptyComponent = _dereq_(37);
|
|
var ReactDOMTextComponent = _dereq_(48);
|
|
var ReactDefaultBatchingStrategy = _dereq_(53);
|
|
var ReactEmptyComponent = _dereq_(55);
|
|
var ReactGenericBatching = _dereq_(60);
|
|
var ReactHostComponent = _dereq_(61);
|
|
var ReactReconcileTransaction = _dereq_(74);
|
|
var ReactUpdates = _dereq_(84);
|
|
|
|
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;
|
|
|
|
ReactGenericBatching.injection.injectStackBatchedUpdates(ReactUpdates.batchedUpdates);
|
|
|
|
ReactHostComponent.injection.injectGenericComponentClass(ReactDOMComponent);
|
|
|
|
ReactHostComponent.injection.injectTextComponentClass(ReactDOMTextComponent);
|
|
|
|
ReactEmptyComponent.injection.injectEmptyComponentFactory(function (instantiate) {
|
|
return new ReactDOMEmptyComponent(instantiate);
|
|
});
|
|
|
|
ReactUpdates.injection.injectReconcileTransaction(ReactReconcileTransaction);
|
|
ReactUpdates.injection.injectBatchingStrategy(ReactDefaultBatchingStrategy);
|
|
|
|
ReactComponentEnvironment.injection.injectEnvironment(ReactComponentBrowserEnvironment);
|
|
}
|
|
|
|
module.exports = {
|
|
inject: inject
|
|
};
|
|
},{"27":27,"28":28,"33":33,"37":37,"48":48,"53":53,"55":55,"60":60,"61":61,"74":74,"84":84}],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 _prodInvariant = _dereq_(129),
|
|
_assign = _dereq_(162);
|
|
|
|
var DOMChildrenOperations = _dereq_(8);
|
|
var DOMLazyTree = _dereq_(10);
|
|
var ReactDOMComponentTree = _dereq_(35);
|
|
|
|
var escapeTextContentForBrowser = _dereq_(109);
|
|
var invariant = _dereq_(154);
|
|
var validateDOMNesting = _dereq_(135);
|
|
|
|
/**
|
|
* 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;
|
|
},{"10":10,"109":109,"129":129,"135":135,"154":154,"162":162,"35":35,"8":8}],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 _prodInvariant = _dereq_(129),
|
|
_assign = _dereq_(162);
|
|
|
|
var ReactControlledValuePropTypes = _dereq_(31);
|
|
var ReactDOMComponentTree = _dereq_(35);
|
|
|
|
var invariant = _dereq_(154);
|
|
var warning = _dereq_(161);
|
|
|
|
var didWarnValDefaultVal = false;
|
|
|
|
/**
|
|
* 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
|
|
});
|
|
|
|
return hostProps;
|
|
},
|
|
|
|
mountWrapper: function (inst, props) {
|
|
if ("development" !== 'production') {
|
|
ReactControlledValuePropTypes.checkPropTypes('textarea', props, inst._currentElement._owner);
|
|
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 = props.value;
|
|
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
|
|
};
|
|
},
|
|
|
|
updateWrapper: function (inst) {
|
|
var props = inst._currentElement.props;
|
|
|
|
var node = ReactDOMComponentTree.getNodeFromInstance(inst);
|
|
var value = props.value;
|
|
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;
|
|
}
|
|
},
|
|
|
|
restoreControlledState: function (inst) {
|
|
if (inst._rootNodeID) {
|
|
// DOM component is still mounted; update
|
|
ReactDOMTextarea.updateWrapper(inst);
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = ReactDOMTextarea;
|
|
},{"129":129,"154":154,"161":161,"162":162,"31":31,"35":35}],50:[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_(162);
|
|
|
|
var ReactDOM = _dereq_(32);
|
|
|
|
var ReactDOMUMDEntry = _assign({
|
|
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
|
|
ReactInstanceMap: _dereq_(64)
|
|
}
|
|
}, ReactDOM);
|
|
|
|
if ("development" !== 'production') {
|
|
_assign(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_(72),
|
|
ReactTestUtils: _dereq_(80)
|
|
});
|
|
}
|
|
|
|
module.exports = ReactDOMUMDEntry;
|
|
},{"162":162,"32":32,"64":64,"72":72,"80":80}],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 DOMProperty = _dereq_(12);
|
|
var EventPluginRegistry = _dereq_(18);
|
|
var ReactComponentTreeHook = _dereq_(136);
|
|
|
|
var warning = _dereq_(161);
|
|
|
|
if ("development" !== 'production') {
|
|
var reactProps = {
|
|
children: true,
|
|
dangerouslySetInnerHTML: true,
|
|
key: true,
|
|
ref: true,
|
|
|
|
autoFocus: true,
|
|
defaultValue: true,
|
|
defaultChecked: 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;
|
|
},{"12":12,"136":136,"161":161,"18":18}],52:[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_(66);
|
|
var ReactHostOperationHistoryHook = _dereq_(62);
|
|
var ReactComponentTreeHook = _dereq_(136);
|
|
var ExecutionEnvironment = _dereq_(140);
|
|
|
|
var performanceNow = _dereq_(159);
|
|
var warning = _dereq_(161);
|
|
|
|
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();
|
|
|
|
var startTime = _lifeCycleTimerStack$.startTime;
|
|
var nestedFlushStartTime = _lifeCycleTimerStack$.nestedFlushStartTime;
|
|
var debugID = _lifeCycleTimerStack$.debugID;
|
|
var timerType = _lifeCycleTimerStack$.timerType;
|
|
|
|
var nestedFlushDuration = performanceNow() - nestedFlushStartTime;
|
|
currentTimerStartTime = startTime;
|
|
currentTimerNestedFlushDuration += nestedFlushDuration;
|
|
currentTimerDebugID = debugID;
|
|
currentTimerType = timerType;
|
|
}
|
|
|
|
var lastMarkTimeStamp = 0;
|
|
var canUsePerformanceMeasure = 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');
|
|
}
|
|
};
|
|
|
|
ReactDebugTool.addHook(ReactInvalidSetStateWarningHook);
|
|
ReactDebugTool.addHook(ReactComponentTreeHook);
|
|
var url = ExecutionEnvironment.canUseDOM && window.location.href || '';
|
|
if (/[?&]react_perf\b/.test(url)) {
|
|
ReactDebugTool.beginProfiling();
|
|
}
|
|
|
|
module.exports = ReactDebugTool;
|
|
},{"136":136,"140":140,"159":159,"161":161,"62":62,"66":66}],53:[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_(162);
|
|
|
|
var ReactUpdates = _dereq_(84);
|
|
var Transaction = _dereq_(102);
|
|
|
|
var emptyFunction = _dereq_(146);
|
|
|
|
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;
|
|
},{"102":102,"146":146,"162":162,"84":84}],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';
|
|
|
|
// 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;
|
|
},{}],55:[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;
|
|
},{}],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 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 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');
|
|
evt.initEvent(evtType, false, false);
|
|
fakeNode.dispatchEvent(evt);
|
|
fakeNode.removeEventListener(evtType, boundFunc, false);
|
|
};
|
|
}
|
|
}
|
|
|
|
module.exports = ReactErrorUtils;
|
|
},{}],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 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}],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 _assign = _dereq_(162);
|
|
|
|
var EventListener = _dereq_(139);
|
|
var ExecutionEnvironment = _dereq_(140);
|
|
var PooledClass = _dereq_(24);
|
|
var ReactDOMComponentTree = _dereq_(35);
|
|
var ReactGenericBatching = _dereq_(60);
|
|
|
|
var getEventTarget = _dereq_(117);
|
|
var getUnboundedScrollPosition = _dereq_(151);
|
|
|
|
/**
|
|
* 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, targetInst) {
|
|
this.topLevelType = topLevelType;
|
|
this.nativeEvent = nativeEvent;
|
|
this.targetInst = targetInst;
|
|
this.ancestors = [];
|
|
}
|
|
_assign(TopLevelCallbackBookKeeping.prototype, {
|
|
destructor: function () {
|
|
this.topLevelType = null;
|
|
this.nativeEvent = null;
|
|
this.targetInst = null;
|
|
this.ancestors.length = 0;
|
|
}
|
|
});
|
|
PooledClass.addPoolingTo(TopLevelCallbackBookKeeping, PooledClass.threeArgumentPooler);
|
|
|
|
function handleTopLevelImpl(bookKeeping) {
|
|
var targetInst = bookKeeping.targetInst;
|
|
|
|
// 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 nativeEventTarget = getEventTarget(nativeEvent);
|
|
var targetInst = ReactDOMComponentTree.getClosestInstanceFromNode(nativeEventTarget);
|
|
|
|
var bookKeeping = TopLevelCallbackBookKeeping.getPooled(topLevelType, nativeEvent, targetInst);
|
|
|
|
try {
|
|
// Event queue being processed in the same cycle allows
|
|
// `preventDefault`.
|
|
ReactGenericBatching.batchedUpdates(handleTopLevelImpl, bookKeeping);
|
|
} finally {
|
|
TopLevelCallbackBookKeeping.release(bookKeeping);
|
|
}
|
|
}
|
|
};
|
|
|
|
module.exports = ReactEventListener;
|
|
},{"117":117,"139":139,"140":140,"151":151,"162":162,"24":24,"35":35,"60":60}],59:[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;
|
|
},{}],60:[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 ReactControlledComponent = _dereq_(30);
|
|
|
|
// Used as a way to call batchedUpdates when we don't know if we're in a Fiber
|
|
// or Stack context. Such as when we're dispatching events or if third party
|
|
// libraries need to call batchedUpdates. Eventually, this API will go away when
|
|
// everything is batched by default. We'll then have a similar API to opt-out of
|
|
// scheduled work and instead do synchronous work.
|
|
|
|
// Defaults
|
|
var stackBatchedUpdates = function (fn, a, b, c, d, e) {
|
|
fn(a, b, c, d, e);
|
|
};
|
|
var fiberPerformSynchronousWork = function (fn, bookkeeping) {
|
|
fn(bookkeeping);
|
|
};
|
|
|
|
function performFiberBatchedUpdates(fn, bookkeeping) {
|
|
// If we have Fiber loaded, we need to wrap this in a batching call so that
|
|
// Fiber can apply its default priority for this call.
|
|
fiberPerformSynchronousWork(fn, bookkeeping);
|
|
}
|
|
function batchedUpdates(fn, bookkeeping) {
|
|
// We first perform work with the stack batching strategy, by passing our
|
|
// indirection to it.
|
|
stackBatchedUpdates(performFiberBatchedUpdates, fn, bookkeeping);
|
|
}
|
|
|
|
var isNestingBatched = false;
|
|
function batchedUpdatesWithControlledComponents(fn, bookkeeping) {
|
|
if (isNestingBatched) {
|
|
// If we are currently inside another batch, we need to wait until it
|
|
// fully completes before restoring state. Therefore, we add the target to
|
|
// a queue of work.
|
|
batchedUpdates(fn, bookkeeping);
|
|
return;
|
|
}
|
|
isNestingBatched = true;
|
|
try {
|
|
batchedUpdates(fn, bookkeeping);
|
|
} finally {
|
|
// Here we wait until all updates have propagated, which is important
|
|
// when using controlled components within layers:
|
|
// https://github.com/facebook/react/issues/1698
|
|
// Then we restore state of any controlled component.
|
|
isNestingBatched = false;
|
|
ReactControlledComponent.restoreStateIfNeeded();
|
|
}
|
|
}
|
|
|
|
var ReactGenericBatchingInjection = {
|
|
injectStackBatchedUpdates: function (_batchedUpdates) {
|
|
stackBatchedUpdates = _batchedUpdates;
|
|
},
|
|
injectFiberPerformSynchronousWork: function (_performSynchronousWork) {
|
|
fiberPerformSynchronousWork = _performSynchronousWork;
|
|
}
|
|
};
|
|
|
|
var ReactGenericBatching = {
|
|
batchedUpdates: batchedUpdatesWithControlledComponents,
|
|
injection: ReactGenericBatchingInjection
|
|
};
|
|
|
|
module.exports = ReactGenericBatching;
|
|
},{"30":30}],61:[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_(129);
|
|
|
|
var invariant = _dereq_(154);
|
|
|
|
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;
|
|
},{"129":129,"154":154}],62:[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;
|
|
},{}],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';
|
|
|
|
var ReactDOMSelection = _dereq_(46);
|
|
|
|
var containsNode = _dereq_(143);
|
|
var focusNode = _dereq_(148);
|
|
var getActiveElement = _dereq_(149);
|
|
|
|
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;
|
|
},{"143":143,"148":148,"149":149,"46":46}],64:[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;
|
|
},{}],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';
|
|
|
|
// Trust the developer to only use ReactInstrumentation with a __DEV__ check
|
|
|
|
var debugTool = null;
|
|
|
|
if ("development" !== 'production') {
|
|
var ReactDebugTool = _dereq_(52);
|
|
debugTool = ReactDebugTool;
|
|
}
|
|
|
|
module.exports = { debugTool: debugTool };
|
|
},{"52":52}],66:[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_(161);
|
|
|
|
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;
|
|
},{"161":161}],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 adler32 = _dereq_(105);
|
|
|
|
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;
|
|
},{"105":105}],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_(129);
|
|
|
|
var DOMLazyTree = _dereq_(10);
|
|
var DOMProperty = _dereq_(12);
|
|
var React = _dereq_(138);
|
|
var ReactBrowserEventEmitter = _dereq_(25);
|
|
var ReactCurrentOwner = _dereq_(137);
|
|
var ReactDOMComponentTree = _dereq_(35);
|
|
var ReactDOMContainerInfo = _dereq_(36);
|
|
var ReactDOMFeatureFlags = _dereq_(38);
|
|
var ReactFeatureFlags = _dereq_(59);
|
|
var ReactInstanceMap = _dereq_(64);
|
|
var ReactInstrumentation = _dereq_(65);
|
|
var ReactMarkupChecksum = _dereq_(67);
|
|
var ReactReconciler = _dereq_(75);
|
|
var ReactUpdateQueue = _dereq_(83);
|
|
var ReactUpdates = _dereq_(84);
|
|
|
|
var emptyObject = _dereq_(147);
|
|
var instantiateReactComponent = _dereq_(125);
|
|
var invariant = _dereq_(154);
|
|
var setInnerHTML = _dereq_(131);
|
|
var shouldUpdateReactComponent = _dereq_(133);
|
|
var warning = _dereq_(161);
|
|
|
|
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) {
|
|
if ("development" !== 'production') {
|
|
ReactInstrumentation.debugTool.onBeginFlush();
|
|
}
|
|
ReactReconciler.unmountComponent(instance, false /* safely */
|
|
, false /* skipLifecycle */
|
|
);
|
|
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, callback) {
|
|
// 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);
|
|
|
|
if (callback) {
|
|
componentInstance._pendingCallbacks = [function () {
|
|
callback.call(componentInstance._renderedComponent.getPublicInstance());
|
|
}];
|
|
}
|
|
|
|
// 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, callback)._renderedComponent.getPublicInstance();
|
|
return component;
|
|
},
|
|
|
|
/**
|
|
* Renders a React component into the DOM in the supplied `container`.
|
|
* See https://facebook.github.io/react/docs/react-dom.html#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/react-dom.html#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);
|
|
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;
|
|
},{"10":10,"12":12,"125":125,"129":129,"131":131,"133":133,"137":137,"138":138,"147":147,"154":154,"161":161,"25":25,"35":35,"36":36,"38":38,"59":59,"64":64,"65":65,"67":67,"75":75,"83":83,"84":84}],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_(129);
|
|
|
|
var ReactComponentEnvironment = _dereq_(28);
|
|
var ReactInstanceMap = _dereq_(64);
|
|
var ReactInstrumentation = _dereq_(65);
|
|
|
|
var ReactCurrentOwner = _dereq_(137);
|
|
var ReactReconciler = _dereq_(75);
|
|
var ReactChildReconciler = _dereq_(26);
|
|
|
|
var emptyFunction = _dereq_(146);
|
|
var flattenChildren = _dereq_(111);
|
|
var invariant = _dereq_(154);
|
|
|
|
/**
|
|
* 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;
|
|
}) : []);
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Provides common functionality for components that must reconcile multiple
|
|
* children. This is used by `ReactDOMComponent` to mount, update, and
|
|
* unmount child components.
|
|
*/
|
|
var ReactMultiChild = {
|
|
_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, /* safely */
|
|
false /* skipLifecycle */
|
|
);
|
|
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, /* safely */
|
|
false /* skipLifecycle */
|
|
);
|
|
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, skipLifecycle) {
|
|
var renderedChildren = this._renderedChildren;
|
|
ReactChildReconciler.unmountChildren(renderedChildren, safely, skipLifecycle);
|
|
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;
|
|
},{"111":111,"129":129,"137":137,"146":146,"154":154,"26":26,"28":28,"64":64,"65":65,"75":75}],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_(129);
|
|
|
|
var React = _dereq_(138);
|
|
|
|
var invariant = _dereq_(154);
|
|
|
|
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;
|
|
},{"129":129,"138":138,"154":154}],71:[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_(129);
|
|
|
|
var invariant = _dereq_(154);
|
|
|
|
/**
|
|
* @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;
|
|
},{"129":129,"154":154}],72:[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_(162);
|
|
|
|
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_(52);
|
|
var warning = _dereq_(161);
|
|
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;
|
|
var treeSnapshot = flush.treeSnapshot;
|
|
|
|
measurements.forEach(function (measurement) {
|
|
var duration = measurement.duration;
|
|
var instanceID = measurement.instanceID;
|
|
var 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];
|
|
var displayName = _treeSnapshot$instanc.displayName;
|
|
var 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;
|
|
var timerType = measurement.timerType;
|
|
|
|
if (timerType !== 'render') {
|
|
return;
|
|
}
|
|
isCompositeByID[instanceID] = true;
|
|
});
|
|
});
|
|
|
|
flushHistory.forEach(function (flush) {
|
|
var measurements = flush.measurements;
|
|
var treeSnapshot = flush.treeSnapshot;
|
|
|
|
measurements.forEach(function (measurement) {
|
|
var duration = measurement.duration;
|
|
var instanceID = measurement.instanceID;
|
|
var 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];
|
|
var displayName = _treeSnapshot$instanc2.displayName;
|
|
var 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;
|
|
var treeSnapshot = flush.treeSnapshot;
|
|
var 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;
|
|
var timerType = measurement.timerType;
|
|
|
|
if (timerType !== 'render') {
|
|
return;
|
|
}
|
|
renderedCompositeIDs[instanceID] = true;
|
|
});
|
|
|
|
measurements.forEach(function (measurement) {
|
|
var duration = measurement.duration;
|
|
var instanceID = measurement.instanceID;
|
|
var 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;
|
|
var treeSnapshot = flush.treeSnapshot;
|
|
|
|
operations.forEach(function (operation) {
|
|
var instanceID = operation.instanceID;
|
|
var type = operation.type;
|
|
var payload = operation.payload;
|
|
var _treeSnapshot$instanc3 = treeSnapshot[instanceID];
|
|
var displayName = _treeSnapshot$instanc3.displayName;
|
|
var 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;
|
|
var instanceCount = item.instanceCount;
|
|
var 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;
|
|
var instanceCount = item.instanceCount;
|
|
var inclusiveRenderDuration = item.inclusiveRenderDuration;
|
|
var 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;
|
|
var instanceCount = item.instanceCount;
|
|
var inclusiveRenderDuration = item.inclusiveRenderDuration;
|
|
var 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;
|
|
},{"161":161,"162":162,"52":52}],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 ReactPropTypeLocationNames = {};
|
|
|
|
if ("development" !== 'production') {
|
|
ReactPropTypeLocationNames = {
|
|
prop: 'prop',
|
|
context: 'context',
|
|
childContext: 'child context'
|
|
};
|
|
}
|
|
|
|
module.exports = ReactPropTypeLocationNames;
|
|
},{}],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_(162);
|
|
|
|
var CallbackQueue = _dereq_(6);
|
|
var PooledClass = _dereq_(24);
|
|
var ReactBrowserEventEmitter = _dereq_(25);
|
|
var ReactInputSelection = _dereq_(63);
|
|
var ReactInstrumentation = _dereq_(65);
|
|
var Transaction = _dereq_(102);
|
|
var ReactUpdateQueue = _dereq_(83);
|
|
|
|
/**
|
|
* 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;
|
|
},{"102":102,"162":162,"24":24,"25":25,"6":6,"63":63,"65":65,"83":83}],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_(65);
|
|
|
|
var warning = _dereq_(161);
|
|
|
|
/**
|
|
* 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, skipLifecycle) {
|
|
if ("development" !== 'production') {
|
|
if (internalInstance._debugID !== 0) {
|
|
ReactInstrumentation.debugTool.onBeforeUnmountComponent(internalInstance._debugID);
|
|
}
|
|
}
|
|
ReactRef.detachRefs(internalInstance, internalInstance._currentElement);
|
|
internalInstance.unmountComponent(safely, skipLifecycle);
|
|
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;
|
|
},{"161":161,"65":65,"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_(71);
|
|
|
|
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;
|
|
},{"71":71}],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_(162);
|
|
|
|
var PooledClass = _dereq_(24);
|
|
var Transaction = _dereq_(102);
|
|
var ReactInstrumentation = _dereq_(65);
|
|
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;
|
|
},{"102":102,"162":162,"24":24,"65":65,"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_(83);
|
|
|
|
var warning = _dereq_(161);
|
|
|
|
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;
|
|
},{"161":161,"83":83}],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.
|
|
*
|
|
* @preventMunge
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var _prodInvariant = _dereq_(129),
|
|
_assign = _dereq_(162);
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
var React = _dereq_(138);
|
|
var ReactDOMInjection = _dereq_(40);
|
|
var ReactDOMStackInjection = _dereq_(47);
|
|
var ReactCompositeComponent = _dereq_(29);
|
|
var ReactReconciler = _dereq_(75);
|
|
var ReactUpdates = _dereq_(84);
|
|
|
|
var emptyObject = _dereq_(147);
|
|
var getNextDebugID = _dereq_(120);
|
|
var invariant = _dereq_(154);
|
|
|
|
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.
|
|
ReactDOMInjection.inject();
|
|
ReactDOMStackInjection.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, /* safely */
|
|
false /* skipLifecycle */
|
|
);
|
|
}
|
|
};
|
|
|
|
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;
|
|
},{"120":120,"129":129,"138":138,"147":147,"154":154,"162":162,"29":29,"40":40,"47":47,"75":75,"84":84}],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_(129),
|
|
_assign = _dereq_(162);
|
|
|
|
var EventConstants = _dereq_(16);
|
|
var EventPluginHub = _dereq_(17);
|
|
var EventPluginRegistry = _dereq_(18);
|
|
var EventPropagators = _dereq_(20);
|
|
var React = _dereq_(138);
|
|
var ReactControlledComponent = _dereq_(30);
|
|
var ReactDOM = _dereq_(32);
|
|
var ReactDOMComponentTree = _dereq_(35);
|
|
var ReactBrowserEventEmitter = _dereq_(25);
|
|
var ReactInstanceMap = _dereq_(64);
|
|
var ReactTypeOfWork = _dereq_(82);
|
|
var ReactGenericBatching = _dereq_(60);
|
|
var SyntheticEvent = _dereq_(93);
|
|
var ReactShallowRenderer = _dereq_(79);
|
|
|
|
var findDOMNode = _dereq_(110);
|
|
var invariant = _dereq_(154);
|
|
|
|
var topLevelTypes = EventConstants.topLevelTypes;
|
|
var ClassComponent = ReactTypeOfWork.ClassComponent;
|
|
var FunctionalComponent = ReactTypeOfWork.FunctionalComponent;
|
|
var HostComponent = ReactTypeOfWork.HostComponent;
|
|
var HostContainer = ReactTypeOfWork.HostContainer;
|
|
var HostText = ReactTypeOfWork.HostText;
|
|
|
|
|
|
function Event(suffix) {}
|
|
|
|
/**
|
|
* @class ReactTestUtils
|
|
*/
|
|
|
|
function findAllInRenderedStackTreeInternal(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(findAllInRenderedStackTreeInternal(renderedChildren[key], test));
|
|
}
|
|
} else if (React.isValidElement(currentElement) && typeof currentElement.type === 'function') {
|
|
ret = ret.concat(findAllInRenderedStackTreeInternal(inst._renderedComponent, test));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
function findAllInRenderedFiberTreeInternal(fiber, test) {
|
|
if (!fiber) {
|
|
return [];
|
|
}
|
|
if (fiber.tag !== ClassComponent && fiber.tag !== FunctionalComponent && fiber.tag !== HostComponent && fiber.tag !== HostText) {
|
|
return [];
|
|
}
|
|
var publicInst = fiber.stateNode;
|
|
var ret = publicInst && test(publicInst) ? [publicInst] : [];
|
|
var child = fiber.child;
|
|
while (child) {
|
|
ret = ret.concat(findAllInRenderedFiberTreeInternal(child, test));
|
|
child = child.sibling;
|
|
}
|
|
// TODO: visit stateNode for coroutines
|
|
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 = typeof internalInstance.tag === 'number' ? internalInstance.type : // Fiber reconciler
|
|
internalInstance._currentElement.type; // Stack reconciler
|
|
|
|
return constructor === type;
|
|
},
|
|
|
|
// TODO: deprecate? It's undocumented and unused.
|
|
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';
|
|
},
|
|
|
|
// TODO: deprecate? It's undocumented and unused.
|
|
isCompositeComponentElementWithType: function (inst, type) {
|
|
var internalInstance = ReactInstanceMap.get(inst);
|
|
var constructor = internalInstance._currentElement.type;
|
|
|
|
return !!(ReactTestUtils.isCompositeComponentElement(inst) && constructor === type);
|
|
},
|
|
|
|
// TODO: deprecate? It's undocumented and unused.
|
|
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;
|
|
var internalInstance = ReactInstanceMap.get(inst);
|
|
if (internalInstance && typeof internalInstance.tag === 'number') {
|
|
var fiber = internalInstance;
|
|
var root = fiber;
|
|
while (root['return']) {
|
|
root = root['return'];
|
|
}
|
|
var isRootCurrent = root.tag === HostContainer && root.stateNode.current === root;
|
|
// Make sure we're introspecting the current tree
|
|
var current = isRootCurrent ? fiber : fiber.alternate;
|
|
return findAllInRenderedFiberTreeInternal(current, test);
|
|
} else {
|
|
return findAllInRenderedStackTreeInternal(internalInstance, 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 targetInst = ReactDOMComponentTree.getInstanceFromNode(node);
|
|
var event = new SyntheticEvent(dispatchConfig, targetInst, 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);
|
|
}
|
|
|
|
ReactGenericBatching.batchedUpdates(function () {
|
|
// Normally extractEvent enqueues a state restore, but we'll just always
|
|
// do that since we we're by-passing it here.
|
|
ReactControlledComponent.enqueueStateRestore(targetInst);
|
|
|
|
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;
|
|
},{"110":110,"129":129,"138":138,"154":154,"16":16,"162":162,"17":17,"18":18,"20":20,"25":25,"30":30,"32":32,"35":35,"60":60,"64":64,"79":79,"82":82,"93":93}],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';
|
|
|
|
/**
|
|
* Return the lowest common ancestor of A and B, or null if they are in
|
|
* different trees.
|
|
*/
|
|
|
|
function getLowestCommonAncestor(instA, instB) {
|
|
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) {
|
|
while (instB) {
|
|
if (instB === instA) {
|
|
return true;
|
|
}
|
|
instB = instB._hostParent;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Return the parent instance of the passed-in instance.
|
|
*/
|
|
function getParentInstance(inst) {
|
|
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
|
|
};
|
|
},{}],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';
|
|
|
|
module.exports = {
|
|
IndeterminateComponent: 0, // Before we know whether it is functional or class
|
|
FunctionalComponent: 1,
|
|
ClassComponent: 2,
|
|
HostContainer: 3, // Root of a host tree. Could be nested inside another node.
|
|
HostComponent: 4,
|
|
HostText: 5,
|
|
CoroutineComponent: 6,
|
|
CoroutineHandlerPhase: 7,
|
|
YieldComponent: 8,
|
|
Fragment: 9
|
|
};
|
|
},{}],83:[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_(129);
|
|
|
|
var ReactCurrentOwner = _dereq_(137);
|
|
var ReactInstanceMap = _dereq_(64);
|
|
var ReactInstrumentation = _dereq_(65);
|
|
var ReactUpdates = _dereq_(84);
|
|
|
|
var invariant = _dereq_(154);
|
|
var warning = _dereq_(161);
|
|
|
|
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;
|
|
},{"129":129,"137":137,"154":154,"161":161,"64":64,"65":65,"84":84}],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 _prodInvariant = _dereq_(129),
|
|
_assign = _dereq_(162);
|
|
|
|
var PooledClass = _dereq_(24);
|
|
var ReactFeatureFlags = _dereq_(59);
|
|
var ReactReconciler = _dereq_(75);
|
|
var Transaction = _dereq_(102);
|
|
|
|
var invariant = _dereq_(154);
|
|
|
|
var dirtyComponents = [];
|
|
var updateBatchNumber = 0;
|
|
|
|
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 TRANSACTION_WRAPPERS = [NESTED_UPDATES];
|
|
|
|
function ReactUpdatesFlushTransaction() {
|
|
this.reinitializeTransaction();
|
|
this.dirtyComponentsLength = null;
|
|
this.reconcileTransaction = ReactUpdates.ReactReconcileTransaction.getPooled(
|
|
/* useCreateElement */true);
|
|
}
|
|
|
|
_assign(ReactUpdatesFlushTransaction.prototype, Transaction, {
|
|
getTransactionWrappers: function () {
|
|
return TRANSACTION_WRAPPERS;
|
|
},
|
|
|
|
destructor: function () {
|
|
this.dirtyComponentsLength = 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.reconcileTransaction.getReactMountReady().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.
|
|
while (dirtyComponents.length) {
|
|
if (dirtyComponents.length) {
|
|
var transaction = ReactUpdatesFlushTransaction.getPooled();
|
|
transaction.perform(runBatchedUpdates, null, transaction);
|
|
ReactUpdatesFlushTransaction.release(transaction);
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
}
|
|
|
|
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;
|
|
},
|
|
|
|
getBatchingStrategy: function () {
|
|
return 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
|
|
};
|
|
|
|
module.exports = ReactUpdates;
|
|
},{"102":102,"129":129,"154":154,"162":162,"24":24,"59":59,"75":75}],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';
|
|
|
|
module.exports = '16.0.0-alpha';
|
|
},{}],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 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;
|
|
},{}],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 EventPropagators = _dereq_(20);
|
|
var ExecutionEnvironment = _dereq_(140);
|
|
var ReactBrowserEventEmitter = _dereq_(25);
|
|
var ReactDOMComponentTree = _dereq_(35);
|
|
var ReactInputSelection = _dereq_(63);
|
|
var SyntheticEvent = _dereq_(93);
|
|
|
|
var getActiveElement = _dereq_(149);
|
|
var isTextInputElement = _dereq_(127);
|
|
var shallowEqual = _dereq_(160);
|
|
|
|
// Node type for document fragments (Node.DOCUMENT_FRAGMENT_NODE).
|
|
var DOC_FRAGMENT_TYPE = 11;
|
|
|
|
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 all listeners exists for this plugin. If none exist, we do
|
|
// not extract events. See #3639.
|
|
var isListeningToAllDependencies = ReactBrowserEventEmitter.isListeningToAllDependencies;
|
|
|
|
/**
|
|
* 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 (targetInst) {
|
|
var containerInfo = targetInst._hostContainerInfo;
|
|
var isDocumentFragment = containerInfo._node && containerInfo._node.nodeType === DOC_FRAGMENT_TYPE;
|
|
var doc = isDocumentFragment ? containerInfo._node : containerInfo._ownerDocument;
|
|
if (!isListeningToAllDependencies('onSelect', doc)) {
|
|
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;
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = SelectEventPlugin;
|
|
},{"127":127,"140":140,"149":149,"160":160,"20":20,"25":25,"35":35,"63":63,"93":93}],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 _prodInvariant = _dereq_(129);
|
|
|
|
var EventPropagators = _dereq_(20);
|
|
var SyntheticAnimationEvent = _dereq_(89);
|
|
var SyntheticClipboardEvent = _dereq_(90);
|
|
var SyntheticEvent = _dereq_(93);
|
|
var SyntheticFocusEvent = _dereq_(94);
|
|
var SyntheticKeyboardEvent = _dereq_(96);
|
|
var SyntheticMouseEvent = _dereq_(97);
|
|
var SyntheticDragEvent = _dereq_(92);
|
|
var SyntheticTouchEvent = _dereq_(98);
|
|
var SyntheticTransitionEvent = _dereq_(99);
|
|
var SyntheticUIEvent = _dereq_(100);
|
|
var SyntheticWheelEvent = _dereq_(101);
|
|
|
|
var getEventCharCode = _dereq_(114);
|
|
var invariant = _dereq_(154);
|
|
|
|
/**
|
|
* 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;
|
|
});
|
|
|
|
function isInteractive(tag) {
|
|
return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';
|
|
}
|
|
|
|
function shouldPreventMouseEvent(inst) {
|
|
if (inst) {
|
|
var disabled = inst._currentElement && inst._currentElement.props.disabled;
|
|
|
|
if (disabled) {
|
|
return isInteractive(inst._tag);
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
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':
|
|
// Disabled elements should not respond to mouse events
|
|
if (shouldPreventMouseEvent(targetInst)) {
|
|
return null;
|
|
}
|
|
/* 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;
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = SimpleEventPlugin;
|
|
},{"100":100,"101":101,"114":114,"129":129,"154":154,"20":20,"89":89,"90":90,"92":92,"93":93,"94":94,"96":96,"97":97,"98":98,"99":99}],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_(93);
|
|
|
|
/**
|
|
* @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;
|
|
},{"93":93}],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 SyntheticEvent = _dereq_(93);
|
|
|
|
/**
|
|
* @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;
|
|
},{"93":93}],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 SyntheticEvent = _dereq_(93);
|
|
|
|
/**
|
|
* @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;
|
|
},{"93":93}],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 SyntheticMouseEvent = _dereq_(97);
|
|
|
|
/**
|
|
* @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;
|
|
},{"97":97}],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 _assign = _dereq_(162);
|
|
|
|
var PooledClass = _dereq_(24);
|
|
|
|
var emptyFunction = _dereq_(146);
|
|
var warning = _dereq_(161);
|
|
|
|
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;
|
|
}
|
|
}
|
|
},{"146":146,"161":161,"162":162,"24":24}],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_(100);
|
|
|
|
/**
|
|
* @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;
|
|
},{"100":100}],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 SyntheticEvent = _dereq_(93);
|
|
|
|
/**
|
|
* @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;
|
|
},{"93":93}],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_(100);
|
|
|
|
var getEventCharCode = _dereq_(114);
|
|
var getEventKey = _dereq_(115);
|
|
var getEventModifierState = _dereq_(116);
|
|
|
|
/**
|
|
* @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;
|
|
},{"100":100,"114":114,"115":115,"116":116}],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 SyntheticUIEvent = _dereq_(100);
|
|
var ViewportMetrics = _dereq_(103);
|
|
|
|
var getEventModifierState = _dereq_(116);
|
|
|
|
/**
|
|
* @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;
|
|
},{"100":100,"103":103,"116":116}],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 SyntheticUIEvent = _dereq_(100);
|
|
|
|
var getEventModifierState = _dereq_(116);
|
|
|
|
/**
|
|
* @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;
|
|
},{"100":100,"116":116}],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 SyntheticEvent = _dereq_(93);
|
|
|
|
/**
|
|
* @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;
|
|
},{"93":93}],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 SyntheticEvent = _dereq_(93);
|
|
|
|
var getEventTarget = _dereq_(117);
|
|
|
|
/**
|
|
* @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;
|
|
},{"117":117,"93":93}],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 SyntheticMouseEvent = _dereq_(97);
|
|
|
|
/**
|
|
* @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;
|
|
},{"97":97}],102:[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_(129);
|
|
|
|
var invariant = _dereq_(154);
|
|
|
|
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 ( // eslint-disable-line space-before-function-paren
|
|
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;
|
|
},{"129":129,"154":154}],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 ViewportMetrics = {
|
|
|
|
currentScrollLeft: 0,
|
|
|
|
currentScrollTop: 0,
|
|
|
|
refreshScrollValues: function (scrollPosition) {
|
|
ViewportMetrics.currentScrollLeft = scrollPosition.x;
|
|
ViewportMetrics.currentScrollTop = scrollPosition.y;
|
|
}
|
|
|
|
};
|
|
|
|
module.exports = ViewportMetrics;
|
|
},{}],104:[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_(129);
|
|
|
|
var invariant = _dereq_(154);
|
|
|
|
/**
|
|
* 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;
|
|
},{"129":129,"154":154}],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.
|
|
*
|
|
*
|
|
*/
|
|
|
|
'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;
|
|
},{}],106:[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_(129);
|
|
|
|
var ReactPropTypeLocationNames = _dereq_(73);
|
|
|
|
var invariant = _dereq_(154);
|
|
var warning = _dereq_(161);
|
|
|
|
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_(136);
|
|
}
|
|
|
|
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);
|
|
} 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_(136);
|
|
}
|
|
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)
|
|
},{"129":129,"136":136,"154":154,"161":161,"73":73}],107:[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;
|
|
},{}],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 CSSProperty = _dereq_(4);
|
|
|
|
var isUnitlessNumber = CSSProperty.isUnitlessNumber;
|
|
|
|
/**
|
|
* 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 '';
|
|
}
|
|
|
|
if (typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) {
|
|
return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers
|
|
}
|
|
|
|
return ('' + value).trim();
|
|
}
|
|
|
|
module.exports = dangerousStyleValue;
|
|
},{"4":4}],109:[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;
|
|
},{}],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';
|
|
|
|
var _prodInvariant = _dereq_(129);
|
|
|
|
var ReactCurrentOwner = _dereq_(137);
|
|
var ReactDOMComponentTree = _dereq_(35);
|
|
var ReactInstanceMap = _dereq_(64);
|
|
|
|
var getHostComponentFromComposite = _dereq_(118);
|
|
var invariant = _dereq_(154);
|
|
var warning = _dereq_(161);
|
|
|
|
/**
|
|
* Returns the DOM node rendered by this element.
|
|
*
|
|
* See https://facebook.github.io/react/docs/react-dom.html#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;
|
|
},{"118":118,"129":129,"137":137,"154":154,"161":161,"35":35,"64":64}],111:[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_(134);
|
|
var warning = _dereq_(161);
|
|
|
|
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_(136);
|
|
}
|
|
|
|
/**
|
|
* @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_(136);
|
|
}
|
|
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)
|
|
},{"134":134,"136":136,"161":161,"23":23}],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';
|
|
|
|
/**
|
|
* @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;
|
|
},{}],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';
|
|
|
|
function getComponentName(instanceOrFiber) {
|
|
if ("development" !== 'production') {
|
|
if (typeof instanceOrFiber.getName === 'function') {
|
|
// Stack reconciler
|
|
var instance = instanceOrFiber;
|
|
return instance.getName() || 'Component';
|
|
}
|
|
if (typeof instanceOrFiber.tag === 'number') {
|
|
// Fiber reconciler
|
|
var fiber = instanceOrFiber;
|
|
var type = fiber.type;
|
|
|
|
if (typeof type === 'string') {
|
|
return type;
|
|
}
|
|
if (typeof type === 'function') {
|
|
return type.displayName || type.name || null;
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
module.exports = getComponentName;
|
|
},{}],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';
|
|
|
|
/**
|
|
* `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;
|
|
},{}],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 getEventCharCode = _dereq_(114);
|
|
|
|
/**
|
|
* 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;
|
|
},{"114":114}],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';
|
|
|
|
/**
|
|
* 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;
|
|
},{}],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';
|
|
|
|
/**
|
|
* 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;
|
|
},{}],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';
|
|
|
|
var ReactNodeTypes = _dereq_(70);
|
|
|
|
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;
|
|
},{"70":70}],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';
|
|
|
|
/* 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;
|
|
},{}],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 nextDebugID = 1;
|
|
|
|
function getNextDebugID() {
|
|
return nextDebugID++;
|
|
}
|
|
|
|
module.exports = getNextDebugID;
|
|
},{}],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';
|
|
|
|
/**
|
|
* 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;
|
|
},{}],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_(140);
|
|
|
|
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;
|
|
},{"140":140}],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';
|
|
|
|
var ExecutionEnvironment = _dereq_(140);
|
|
|
|
/**
|
|
* 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;
|
|
},{"140":140}],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 ReactDOMComponentTree = _dereq_(35);
|
|
|
|
function isCheckable(elem) {
|
|
var type = elem.type;
|
|
var nodeName = elem.nodeName;
|
|
return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio');
|
|
}
|
|
|
|
function getTracker(inst) {
|
|
return inst._wrapperState.valueTracker;
|
|
}
|
|
|
|
function attachTracker(inst, tracker) {
|
|
inst._wrapperState.valueTracker = tracker;
|
|
}
|
|
|
|
function detachTracker(inst) {
|
|
delete inst._wrapperState.valueTracker;
|
|
}
|
|
|
|
function getValueFromNode(node) {
|
|
var value;
|
|
if (node) {
|
|
value = isCheckable(node) ? '' + node.checked : node.value;
|
|
}
|
|
return value;
|
|
}
|
|
|
|
var inputValueTracking = {
|
|
// exposed for testing
|
|
_getTrackerFromNode: function (node) {
|
|
return getTracker(ReactDOMComponentTree.getInstanceFromNode(node));
|
|
},
|
|
|
|
|
|
track: function (inst) {
|
|
if (getTracker(inst)) {
|
|
return;
|
|
}
|
|
|
|
var node = ReactDOMComponentTree.getNodeFromInstance(inst);
|
|
var valueField = isCheckable(node) ? 'checked' : 'value';
|
|
var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField);
|
|
|
|
var currentValue = '' + node[valueField];
|
|
|
|
// if someone has already defined a value or Safari, then bail
|
|
// and don't track value will cause over reporting of changes,
|
|
// but it's better then a hard failure
|
|
// (needed for certain tests that spyOn input values and Safari)
|
|
if (node.hasOwnProperty(valueField) || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') {
|
|
return;
|
|
}
|
|
|
|
Object.defineProperty(node, valueField, {
|
|
enumerable: descriptor.enumerable,
|
|
configurable: true,
|
|
get: function () {
|
|
return descriptor.get.call(this);
|
|
},
|
|
set: function (value) {
|
|
currentValue = '' + value;
|
|
descriptor.set.call(this, value);
|
|
}
|
|
});
|
|
|
|
attachTracker(inst, {
|
|
getValue: function () {
|
|
return currentValue;
|
|
},
|
|
setValue: function (value) {
|
|
currentValue = '' + value;
|
|
},
|
|
stopTracking: function () {
|
|
detachTracker(inst);
|
|
delete node[valueField];
|
|
}
|
|
});
|
|
},
|
|
|
|
updateValueIfChanged: function (inst) {
|
|
if (!inst) {
|
|
return false;
|
|
}
|
|
var tracker = getTracker(inst);
|
|
|
|
if (!tracker) {
|
|
inputValueTracking.track(inst);
|
|
return true;
|
|
}
|
|
|
|
var lastValue = tracker.getValue();
|
|
var nextValue = getValueFromNode(ReactDOMComponentTree.getNodeFromInstance(inst));
|
|
|
|
if (nextValue !== lastValue) {
|
|
tracker.setValue(nextValue);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
},
|
|
stopTracking: function (inst) {
|
|
var tracker = getTracker(inst);
|
|
if (tracker) {
|
|
tracker.stopTracking();
|
|
}
|
|
}
|
|
};
|
|
|
|
module.exports = inputValueTracking;
|
|
},{"35":35}],125:[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_(129),
|
|
_assign = _dereq_(162);
|
|
|
|
var ReactCompositeComponent = _dereq_(29);
|
|
var ReactEmptyComponent = _dereq_(55);
|
|
var ReactHostComponent = _dereq_(61);
|
|
|
|
var getNextDebugID = _dereq_(120);
|
|
var invariant = _dereq_(154);
|
|
var warning = _dereq_(161);
|
|
|
|
// 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;
|
|
!(element && (typeof element.type === 'function' || typeof element.type === 'string')) ? "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', element.type == null ? element.type : typeof element.type, getDeclarationErrorAddendum(element._owner)) : _prodInvariant('130', element.type == null ? element.type : typeof element.type, getDeclarationErrorAddendum(element._owner)) : 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;
|
|
},{"120":120,"129":129,"154":154,"161":161,"162":162,"29":29,"55":55,"61":61}],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 ExecutionEnvironment = _dereq_(140);
|
|
|
|
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;
|
|
},{"140":140}],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';
|
|
|
|
/**
|
|
* @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;
|
|
},{}],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 escapeTextContentForBrowser = _dereq_(109);
|
|
|
|
/**
|
|
* 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;
|
|
},{"109":109}],129:[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;
|
|
},{}],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 ReactMount = _dereq_(68);
|
|
|
|
module.exports = ReactMount.renderSubtreeIntoContainer;
|
|
},{"68":68}],131:[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_(140);
|
|
var DOMNamespaces = _dereq_(11);
|
|
|
|
var WHITESPACE_TEST = /^[ \r\n\t\f]/;
|
|
var NONVISIBLE_TEST = /<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/;
|
|
|
|
var createMicrosoftUnsafeLocalFunction = _dereq_(107);
|
|
|
|
// 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;
|
|
},{"107":107,"11":11,"140":140}],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.
|
|
*
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var ExecutionEnvironment = _dereq_(140);
|
|
var escapeTextContentForBrowser = _dereq_(109);
|
|
var setInnerHTML = _dereq_(131);
|
|
|
|
/**
|
|
* 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;
|
|
},{"109":109,"131":131,"140":140}],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.
|
|
*
|
|
*/
|
|
|
|
'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;
|
|
},{}],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.
|
|
*
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var _prodInvariant = _dereq_(129);
|
|
|
|
var ReactCurrentOwner = _dereq_(137);
|
|
var REACT_ELEMENT_TYPE = _dereq_(54);
|
|
|
|
var getIteratorFn = _dereq_(119);
|
|
var invariant = _dereq_(154);
|
|
var KeyEscapeUtils = _dereq_(23);
|
|
var warning = _dereq_(161);
|
|
|
|
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;
|
|
},{"119":119,"129":129,"137":137,"154":154,"161":161,"23":23,"54":54}],135:[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_(162);
|
|
|
|
var emptyFunction = _dereq_(146);
|
|
var getComponentName = _dereq_(113);
|
|
var warning = _dereq_(161);
|
|
|
|
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 getComponentName(inst) || UNKNOWN;
|
|
});
|
|
var ancestorOwnerNames = ancestorOwners.slice(deepestCommon + 1).map(function (inst) {
|
|
return getComponentName(inst) || 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 ? getComponentName(childOwners[deepestCommon]) || 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;
|
|
},{"113":113,"146":146,"161":161,"162":162}],136:[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;
|
|
},{}],137:[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;
|
|
},{}],138:[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;
|
|
},{}],139:[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_(146);
|
|
|
|
/**
|
|
* 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;
|
|
},{"146":146}],140:[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;
|
|
},{}],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
|
|
*/
|
|
|
|
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;
|
|
},{}],142:[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_(141);
|
|
|
|
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;
|
|
},{"141":141}],143:[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_(156);
|
|
|
|
/*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;
|
|
},{"156":156}],144:[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_(154);
|
|
|
|
/**
|
|
* 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;
|
|
},{"154":154}],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/unsafe-html*/
|
|
|
|
var ExecutionEnvironment = _dereq_(140);
|
|
|
|
var createArrayFromMixed = _dereq_(144);
|
|
var getMarkupWrap = _dereq_(150);
|
|
var invariant = _dereq_(154);
|
|
|
|
/**
|
|
* 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;
|
|
},{"140":140,"144":144,"150":150,"154":154}],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.
|
|
*
|
|
*
|
|
*/
|
|
|
|
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;
|
|
},{}],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.
|
|
*
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var emptyObject = {};
|
|
|
|
if ("development" !== 'production') {
|
|
Object.freeze(emptyObject);
|
|
}
|
|
|
|
module.exports = emptyObject;
|
|
},{}],148:[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;
|
|
},{}],149:[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;
|
|
},{}],150:[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_(140);
|
|
|
|
var invariant = _dereq_(154);
|
|
|
|
/**
|
|
* 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;
|
|
},{"140":140,"154":154}],151:[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;
|
|
},{}],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 _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;
|
|
},{}],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
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var hyphenate = _dereq_(152);
|
|
|
|
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;
|
|
},{"152":152}],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.
|
|
*
|
|
*/
|
|
|
|
'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.
|
|
*/
|
|
|
|
function invariant(condition, format, a, b, c, d, e, f) {
|
|
if ("development" !== 'production') {
|
|
if (format === undefined) {
|
|
throw new Error('invariant requires an error message argument');
|
|
}
|
|
}
|
|
|
|
if (!condition) {
|
|
var error;
|
|
if (format === undefined) {
|
|
error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.');
|
|
} else {
|
|
var args = [a, b, c, d, e, f];
|
|
var argIndex = 0;
|
|
error = new Error(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;
|
|
},{}],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
|
|
*/
|
|
|
|
/**
|
|
* @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;
|
|
},{}],156:[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_(155);
|
|
|
|
/**
|
|
* @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;
|
|
},{"155":155}],157:[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;
|
|
},{}],158:[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_(140);
|
|
|
|
var performance;
|
|
|
|
if (ExecutionEnvironment.canUseDOM) {
|
|
performance = window.performance || window.msPerformance || window.webkitPerformance;
|
|
}
|
|
|
|
module.exports = performance || {};
|
|
},{"140":140}],159:[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_(158);
|
|
|
|
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;
|
|
},{"158":158}],160:[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;
|
|
},{}],161:[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_(146);
|
|
|
|
/**
|
|
* 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;
|
|
},{"146":146}],162:[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;
|
|
};
|
|
|
|
},{}]},{},[50])(50)
|
|
});
|
|
});
|