react 0.13.3 → 0.14.0-beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/addons.js +7 -0
- package/dist/JSXTransformer.js +4101 -2432
- package/dist/react-with-addons.js +4389 -6277
- package/dist/react-with-addons.min.js +6 -8
- package/dist/react.js +4028 -5697
- package/dist/react.min.js +5 -6
- package/lib/{AutoFocusMixin.js → AutoFocusUtils.js} +16 -5
- package/lib/BeforeInputEventPlugin.js +30 -118
- package/lib/CSSCore.js +12 -23
- package/lib/CSSProperty.js +4 -3
- package/lib/CSSPropertyOperations.js +14 -30
- package/lib/CallbackQueue.js +7 -10
- package/lib/ChangeEventPlugin.js +26 -88
- package/lib/ClientReactRootIndex.js +2 -2
- package/lib/DOMChildrenOperations.js +13 -33
- package/lib/DOMProperty.js +86 -147
- package/lib/DOMPropertyOperations.js +91 -67
- package/lib/Danger.js +19 -62
- package/lib/DefaultEventPluginOrder.js +2 -12
- package/lib/EnterLeaveEventPlugin.js +11 -33
- package/lib/EventConstants.js +2 -2
- package/lib/EventListener.js +11 -13
- package/lib/EventPluginHub.js +44 -47
- package/lib/EventPluginRegistry.js +18 -74
- package/lib/EventPluginUtils.js +33 -44
- package/lib/EventPropagators.js +23 -26
- package/lib/ExecutionEnvironment.js +4 -8
- package/lib/FallbackCompositionState.js +3 -3
- package/lib/HTMLDOMPropertyConfig.js +15 -20
- package/lib/LinkedStateMixin.js +3 -6
- package/lib/LinkedValueUtils.js +71 -89
- package/lib/Object.assign.js +1 -1
- package/lib/PooledClass.js +20 -11
- package/lib/React.js +9 -129
- package/lib/ReactBrowserComponentMixin.js +9 -2
- package/lib/ReactBrowserEventEmitter.js +26 -82
- package/lib/ReactCSSTransitionGroup.js +13 -24
- package/lib/ReactCSSTransitionGroupChild.js +26 -28
- package/lib/ReactChildReconciler.js +11 -19
- package/lib/ReactChildren.js +24 -31
- package/lib/ReactClass.js +96 -267
- package/lib/ReactComponent.js +28 -57
- package/lib/ReactComponentBrowserEnvironment.js +4 -8
- package/lib/ReactComponentEnvironment.js +6 -12
- package/lib/ReactComponentWithPureRenderMixin.js +6 -7
- package/lib/ReactCompositeComponent.js +115 -381
- package/lib/ReactCurrentOwner.js +1 -3
- package/lib/ReactDOM.js +4 -2
- package/lib/ReactDOMButton.js +16 -28
- package/lib/ReactDOMClient.js +90 -0
- package/lib/ReactDOMComponent.js +468 -156
- package/lib/ReactDOMIDOperations.js +25 -22
- package/lib/ReactDOMInput.js +79 -108
- package/lib/ReactDOMOption.js +58 -20
- package/lib/ReactDOMSelect.js +95 -83
- package/lib/ReactDOMSelection.js +5 -20
- package/lib/ReactDOMServer.js +24 -0
- package/lib/ReactDOMTextComponent.js +17 -18
- package/lib/ReactDOMTextarea.js +44 -69
- package/lib/ReactDefaultBatchingStrategy.js +9 -13
- package/lib/ReactDefaultInjection.js +20 -76
- package/lib/ReactDefaultPerf.js +36 -69
- package/lib/ReactDefaultPerfAnalysis.js +8 -14
- package/lib/ReactElement.js +26 -120
- package/lib/ReactElementValidator.js +56 -192
- package/lib/ReactEmptyComponent.js +7 -11
- package/lib/ReactErrorUtils.js +3 -3
- package/lib/ReactEventEmitterMixin.js +3 -13
- package/lib/ReactEventListener.js +58 -40
- package/lib/ReactFragment.js +33 -59
- package/lib/ReactInjection.js +1 -1
- package/lib/ReactInputSelection.js +14 -23
- package/lib/ReactInstanceHandles.js +29 -58
- package/lib/ReactInstanceMap.js +5 -5
- package/lib/ReactIsomorphic.js +70 -0
- package/lib/ReactLink.js +2 -4
- package/lib/ReactMarkupChecksum.js +5 -10
- package/lib/ReactMount.js +142 -285
- package/lib/ReactMultiChild.js +19 -45
- package/lib/ReactMultiChildUpdateTypes.js +1 -1
- package/lib/ReactNativeComponent.js +6 -15
- package/lib/ReactNoopUpdateQueue.js +118 -0
- package/lib/ReactOwner.js +7 -24
- package/lib/ReactPerf.js +8 -12
- package/lib/ReactPropTransferer.js +4 -4
- package/lib/ReactPropTypeLocationNames.js +2 -2
- package/lib/ReactPropTypeLocations.js +1 -1
- package/lib/ReactPropTypes.js +41 -61
- package/lib/ReactReconcileTransaction.js +11 -36
- package/lib/ReactReconciler.js +14 -26
- package/lib/ReactRef.js +5 -8
- package/lib/ReactRootIndex.js +2 -2
- package/lib/ReactServerBatchingStrategy.js +23 -0
- package/lib/ReactServerRendering.js +20 -15
- package/lib/ReactServerRenderingTransaction.js +9 -34
- package/lib/ReactStateSetters.js +6 -6
- package/lib/ReactTestUtils.js +137 -190
- package/lib/ReactTransitionChildMapping.js +5 -7
- package/lib/ReactTransitionEvents.js +5 -5
- package/lib/ReactTransitionGroup.js +30 -52
- package/lib/ReactUpdateQueue.js +69 -107
- package/lib/ReactUpdates.js +26 -81
- package/lib/ReactWithAddons.js +5 -6
- package/lib/SVGDOMPropertyConfig.js +39 -4
- package/lib/SelectEventPlugin.js +31 -33
- package/lib/ServerReactRootIndex.js +2 -2
- package/lib/SimpleEventPlugin.js +138 -130
- package/lib/SyntheticClipboardEvent.js +5 -9
- package/lib/SyntheticCompositionEvent.js +4 -10
- package/lib/SyntheticDragEvent.js +3 -3
- package/lib/SyntheticEvent.js +14 -15
- package/lib/SyntheticFocusEvent.js +3 -3
- package/lib/SyntheticInputEvent.js +4 -10
- package/lib/SyntheticKeyboardEvent.js +6 -6
- package/lib/SyntheticMouseEvent.js +10 -16
- package/lib/SyntheticTouchEvent.js +3 -3
- package/lib/SyntheticUIEvent.js +5 -5
- package/lib/SyntheticWheelEvent.js +13 -17
- package/lib/Transaction.js +22 -28
- package/lib/ViewportMetrics.js +2 -2
- package/lib/accumulateInto.js +2 -5
- package/lib/adler32.js +2 -4
- package/lib/camelize.js +4 -2
- package/lib/camelizeStyleName.js +2 -2
- package/lib/cloneWithProps.js +6 -12
- package/lib/containsNode.js +29 -16
- package/lib/createArrayFromMixed.js +17 -16
- package/lib/createNodesFromMarkup.js +6 -8
- package/lib/dangerousStyleValue.js +2 -3
- package/lib/deprecated.js +47 -0
- package/lib/emptyFunction.js +10 -4
- package/lib/emptyObject.js +1 -1
- package/lib/escapeTextContentForBrowser.js +1 -1
- package/lib/findDOMNode.js +7 -27
- package/lib/flattenChildren.js +4 -10
- package/lib/focusNode.js +2 -3
- package/lib/forEachAccumulated.js +3 -3
- package/lib/getActiveElement.js +4 -2
- package/lib/getEventCharCode.js +2 -2
- package/lib/getEventKey.js +1 -1
- package/lib/getEventModifierState.js +1 -2
- package/lib/getEventTarget.js +1 -1
- package/lib/getIteratorFn.js +2 -4
- package/lib/getMarkupWrap.js +18 -40
- package/lib/getNodeForCharacterOffset.js +1 -1
- package/lib/getTextContentAccessor.js +2 -4
- package/lib/getUnboundedScrollPosition.js +1 -1
- package/lib/hyphenate.js +3 -1
- package/lib/hyphenateStyleName.js +2 -2
- package/lib/instantiateReactComponent.js +23 -43
- package/lib/invariant.js +8 -12
- package/lib/isEventSupported.js +7 -10
- package/lib/isNode.js +4 -6
- package/lib/isTextInputElement.js +3 -4
- package/lib/isTextNode.js +3 -1
- package/lib/joinClasses.js +3 -3
- package/lib/keyMirror.js +3 -6
- package/lib/keyOf.js +4 -3
- package/lib/mapObject.js +1 -1
- package/lib/memoizeStringOnly.js +2 -2
- package/lib/onlyChild.js +2 -5
- package/lib/performance.js +2 -5
- package/lib/performanceNow.js +3 -1
- package/lib/quoteAttributeValueForBrowser.js +1 -1
- package/lib/renderSubtreeIntoContainer.js +16 -0
- package/lib/setInnerHTML.js +11 -8
- package/lib/setTextContent.js +3 -3
- package/lib/shallowCompare.js +24 -0
- package/lib/shallowEqual.js +17 -11
- package/lib/shouldUpdateReactComponent.js +3 -64
- package/lib/toArray.js +8 -19
- package/lib/traverseAllChildren.js +23 -90
- package/lib/update.js +25 -85
- package/lib/validateDOMNesting.js +363 -0
- package/lib/warning.js +15 -17
- package/package.json +3 -3
- package/react.js +53 -1
- package/lib/LocalEventTrapMixin.js +0 -53
- package/lib/MobileSafariClickEventPlugin.js +0 -56
- package/lib/ReactContext.js +0 -74
- package/lib/ReactDOMForm.js +0 -47
- package/lib/ReactDOMIframe.js +0 -43
- package/lib/ReactDOMImg.js +0 -44
- package/lib/ReactLifeCycle.js +0 -35
- package/lib/ReactPutListenerQueue.js +0 -54
- package/lib/createFullPageComponent.js +0 -58
- package/lib/cx.js +0 -52
- package/lib/getReactRootElementInContainer.js +0 -33
package/lib/ReactCurrentOwner.js
CHANGED
|
@@ -16,8 +16,6 @@
|
|
|
16
16
|
*
|
|
17
17
|
* The current owner is the component who should own any components that are
|
|
18
18
|
* currently being constructed.
|
|
19
|
-
*
|
|
20
|
-
* The depth indicate how many composite components are above this render level.
|
|
21
19
|
*/
|
|
22
20
|
var ReactCurrentOwner = {
|
|
23
21
|
|
|
@@ -29,4 +27,4 @@ var ReactCurrentOwner = {
|
|
|
29
27
|
|
|
30
28
|
};
|
|
31
29
|
|
|
32
|
-
module.exports = ReactCurrentOwner;
|
|
30
|
+
module.exports = ReactCurrentOwner;
|
package/lib/ReactDOM.js
CHANGED
|
@@ -24,7 +24,7 @@ var mapObject = require("./mapObject");
|
|
|
24
24
|
* @private
|
|
25
25
|
*/
|
|
26
26
|
function createDOMFactory(tag) {
|
|
27
|
-
if (
|
|
27
|
+
if ('production' !== process.env.NODE_ENV) {
|
|
28
28
|
return ReactElementValidator.createFactory(tag);
|
|
29
29
|
}
|
|
30
30
|
return ReactElement.createFactory(tag);
|
|
@@ -84,6 +84,7 @@ var ReactDOM = mapObject({
|
|
|
84
84
|
h6: 'h6',
|
|
85
85
|
head: 'head',
|
|
86
86
|
header: 'header',
|
|
87
|
+
hgroup: 'hgroup',
|
|
87
88
|
hr: 'hr',
|
|
88
89
|
html: 'html',
|
|
89
90
|
i: 'i',
|
|
@@ -156,6 +157,7 @@ var ReactDOM = mapObject({
|
|
|
156
157
|
defs: 'defs',
|
|
157
158
|
ellipse: 'ellipse',
|
|
158
159
|
g: 'g',
|
|
160
|
+
image: 'image',
|
|
159
161
|
line: 'line',
|
|
160
162
|
linearGradient: 'linearGradient',
|
|
161
163
|
mask: 'mask',
|
|
@@ -172,4 +174,4 @@ var ReactDOM = mapObject({
|
|
|
172
174
|
|
|
173
175
|
}, createDOMFactory);
|
|
174
176
|
|
|
175
|
-
module.exports = ReactDOM;
|
|
177
|
+
module.exports = ReactDOM;
|
package/lib/ReactDOMButton.js
CHANGED
|
@@ -11,52 +11,40 @@
|
|
|
11
11
|
|
|
12
12
|
'use strict';
|
|
13
13
|
|
|
14
|
-
var
|
|
15
|
-
var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
|
|
16
|
-
var ReactClass = require("./ReactClass");
|
|
17
|
-
var ReactElement = require("./ReactElement");
|
|
18
|
-
|
|
19
|
-
var keyMirror = require("./keyMirror");
|
|
20
|
-
|
|
21
|
-
var button = ReactElement.createFactory('button');
|
|
22
|
-
|
|
23
|
-
var mouseListenerNames = keyMirror({
|
|
14
|
+
var mouseListenerNames = {
|
|
24
15
|
onClick: true,
|
|
25
16
|
onDoubleClick: true,
|
|
26
17
|
onMouseDown: true,
|
|
27
18
|
onMouseMove: true,
|
|
28
19
|
onMouseUp: true,
|
|
20
|
+
|
|
29
21
|
onClickCapture: true,
|
|
30
22
|
onDoubleClickCapture: true,
|
|
31
23
|
onMouseDownCapture: true,
|
|
32
24
|
onMouseMoveCapture: true,
|
|
33
25
|
onMouseUpCapture: true
|
|
34
|
-
}
|
|
26
|
+
};
|
|
35
27
|
|
|
36
28
|
/**
|
|
37
29
|
* Implements a <button> native component that does not receive mouse events
|
|
38
30
|
* when `disabled` is set.
|
|
39
31
|
*/
|
|
40
|
-
var ReactDOMButton =
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
render: function() {
|
|
47
|
-
var props = {};
|
|
32
|
+
var ReactDOMButton = {
|
|
33
|
+
getNativeProps: function (inst, props, context) {
|
|
34
|
+
if (!props.disabled) {
|
|
35
|
+
return props;
|
|
36
|
+
}
|
|
48
37
|
|
|
49
|
-
// Copy the props
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
38
|
+
// Copy the props, except the mouse listeners
|
|
39
|
+
var nativeProps = {};
|
|
40
|
+
for (var key in props) {
|
|
41
|
+
if (props.hasOwnProperty(key) && !mouseListenerNames[key]) {
|
|
42
|
+
nativeProps[key] = props[key];
|
|
54
43
|
}
|
|
55
44
|
}
|
|
56
45
|
|
|
57
|
-
return
|
|
46
|
+
return nativeProps;
|
|
58
47
|
}
|
|
48
|
+
};
|
|
59
49
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
module.exports = ReactDOMButton;
|
|
50
|
+
module.exports = ReactDOMButton;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2013-2015, Facebook, Inc.
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the BSD-style license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree. An additional grant
|
|
7
|
+
* of patent rights can be found in the PATENTS file in the same directory.
|
|
8
|
+
*
|
|
9
|
+
* @providesModule ReactDOMClient
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/* globals __REACT_DEVTOOLS_GLOBAL_HOOK__*/
|
|
13
|
+
|
|
14
|
+
'use strict';
|
|
15
|
+
|
|
16
|
+
var ReactCurrentOwner = require("./ReactCurrentOwner");
|
|
17
|
+
var ReactDOMTextComponent = require("./ReactDOMTextComponent");
|
|
18
|
+
var ReactDefaultInjection = require("./ReactDefaultInjection");
|
|
19
|
+
var ReactInstanceHandles = require("./ReactInstanceHandles");
|
|
20
|
+
var ReactMount = require("./ReactMount");
|
|
21
|
+
var ReactPerf = require("./ReactPerf");
|
|
22
|
+
var ReactReconciler = require("./ReactReconciler");
|
|
23
|
+
var ReactUpdates = require("./ReactUpdates");
|
|
24
|
+
|
|
25
|
+
var findDOMNode = require("./findDOMNode");
|
|
26
|
+
var renderSubtreeIntoContainer = require("./renderSubtreeIntoContainer");
|
|
27
|
+
var warning = require("./warning");
|
|
28
|
+
|
|
29
|
+
ReactDefaultInjection.inject();
|
|
30
|
+
|
|
31
|
+
var render = ReactPerf.measure('React', 'render', ReactMount.render);
|
|
32
|
+
|
|
33
|
+
var React = {
|
|
34
|
+
findDOMNode: findDOMNode,
|
|
35
|
+
render: render,
|
|
36
|
+
unmountComponentAtNode: ReactMount.unmountComponentAtNode,
|
|
37
|
+
|
|
38
|
+
/* eslint-disable camelcase */
|
|
39
|
+
unstable_batchedUpdates: ReactUpdates.batchedUpdates,
|
|
40
|
+
unstable_renderSubtreeIntoContainer: renderSubtreeIntoContainer
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// Inject the runtime into a devtools global hook regardless of browser.
|
|
44
|
+
// Allows for debugging when the hook is injected on the page.
|
|
45
|
+
if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject === 'function') {
|
|
46
|
+
__REACT_DEVTOOLS_GLOBAL_HOOK__.inject({
|
|
47
|
+
CurrentOwner: ReactCurrentOwner,
|
|
48
|
+
InstanceHandles: ReactInstanceHandles,
|
|
49
|
+
Mount: ReactMount,
|
|
50
|
+
Reconciler: ReactReconciler,
|
|
51
|
+
TextComponent: ReactDOMTextComponent
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if ('production' !== process.env.NODE_ENV) {
|
|
56
|
+
var ExecutionEnvironment = require("./ExecutionEnvironment");
|
|
57
|
+
if (ExecutionEnvironment.canUseDOM && window.top === window.self) {
|
|
58
|
+
|
|
59
|
+
// If we're in Chrome, look for the devtools marker and provide a download
|
|
60
|
+
// link if not installed.
|
|
61
|
+
if (navigator.userAgent.indexOf('Chrome') > -1) {
|
|
62
|
+
if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
|
|
63
|
+
console.debug('Download the React DevTools for a better development experience: ' + 'https://fb.me/react-devtools');
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// If we're in IE8, check to see if we are in combatibility mode and provide
|
|
68
|
+
// information on preventing compatibility mode
|
|
69
|
+
var ieCompatibilityMode = document.documentMode && document.documentMode < 8;
|
|
70
|
+
|
|
71
|
+
'production' !== process.env.NODE_ENV ? 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" />') : undefined;
|
|
72
|
+
|
|
73
|
+
var expectedFeatures = [
|
|
74
|
+
// shims
|
|
75
|
+
Array.isArray, Array.prototype.every, Array.prototype.forEach, Array.prototype.indexOf, Array.prototype.map, Date.now, Function.prototype.bind, Object.keys, String.prototype.split, String.prototype.trim,
|
|
76
|
+
|
|
77
|
+
// shams
|
|
78
|
+
Object.create, Object.freeze];
|
|
79
|
+
|
|
80
|
+
for (var i = 0; i < expectedFeatures.length; i++) {
|
|
81
|
+
if (!expectedFeatures[i]) {
|
|
82
|
+
console.error('One or more ES5 shim/shams expected by React are not available: ' + 'https://fb.me/react-warning-polyfills');
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
module.exports = React;
|
|
90
|
+
/* eslint-enable camelcase */
|
package/lib/ReactDOMComponent.js
CHANGED
|
@@ -14,21 +14,30 @@
|
|
|
14
14
|
|
|
15
15
|
'use strict';
|
|
16
16
|
|
|
17
|
+
var AutoFocusUtils = require("./AutoFocusUtils");
|
|
17
18
|
var CSSPropertyOperations = require("./CSSPropertyOperations");
|
|
18
19
|
var DOMProperty = require("./DOMProperty");
|
|
19
20
|
var DOMPropertyOperations = require("./DOMPropertyOperations");
|
|
21
|
+
var EventConstants = require("./EventConstants");
|
|
20
22
|
var ReactBrowserEventEmitter = require("./ReactBrowserEventEmitter");
|
|
21
|
-
var ReactComponentBrowserEnvironment =
|
|
22
|
-
|
|
23
|
+
var ReactComponentBrowserEnvironment = require("./ReactComponentBrowserEnvironment");
|
|
24
|
+
var ReactDOMButton = require("./ReactDOMButton");
|
|
25
|
+
var ReactDOMInput = require("./ReactDOMInput");
|
|
26
|
+
var ReactDOMOption = require("./ReactDOMOption");
|
|
27
|
+
var ReactDOMSelect = require("./ReactDOMSelect");
|
|
28
|
+
var ReactDOMTextarea = require("./ReactDOMTextarea");
|
|
23
29
|
var ReactMount = require("./ReactMount");
|
|
24
30
|
var ReactMultiChild = require("./ReactMultiChild");
|
|
25
31
|
var ReactPerf = require("./ReactPerf");
|
|
32
|
+
var ReactUpdateQueue = require("./ReactUpdateQueue");
|
|
26
33
|
|
|
27
34
|
var assign = require("./Object.assign");
|
|
28
35
|
var escapeTextContentForBrowser = require("./escapeTextContentForBrowser");
|
|
29
36
|
var invariant = require("./invariant");
|
|
30
37
|
var isEventSupported = require("./isEventSupported");
|
|
31
38
|
var keyOf = require("./keyOf");
|
|
39
|
+
var shallowEqual = require("./shallowEqual");
|
|
40
|
+
var validateDOMNesting = require("./validateDOMNesting");
|
|
32
41
|
var warning = require("./warning");
|
|
33
42
|
|
|
34
43
|
var deleteListener = ReactBrowserEventEmitter.deleteListener;
|
|
@@ -36,82 +45,200 @@ var listenTo = ReactBrowserEventEmitter.listenTo;
|
|
|
36
45
|
var registrationNameModules = ReactBrowserEventEmitter.registrationNameModules;
|
|
37
46
|
|
|
38
47
|
// For quickly matching children type, to test if can be treated as content.
|
|
39
|
-
var CONTENT_TYPES = {'string': true, 'number': true};
|
|
48
|
+
var CONTENT_TYPES = { 'string': true, 'number': true };
|
|
40
49
|
|
|
41
|
-
var STYLE = keyOf({style: null});
|
|
50
|
+
var STYLE = keyOf({ style: null });
|
|
42
51
|
|
|
43
52
|
var ELEMENT_NODE_TYPE = 1;
|
|
44
53
|
|
|
54
|
+
var canDefineProperty = false;
|
|
55
|
+
try {
|
|
56
|
+
Object.defineProperty({}, 'test', { get: function () {} });
|
|
57
|
+
canDefineProperty = true;
|
|
58
|
+
} catch (e) {}
|
|
59
|
+
|
|
60
|
+
function getDeclarationErrorAddendum(internalInstance) {
|
|
61
|
+
if (internalInstance) {
|
|
62
|
+
var owner = internalInstance._currentElement._owner || null;
|
|
63
|
+
if (owner) {
|
|
64
|
+
var name = owner.getName();
|
|
65
|
+
if (name) {
|
|
66
|
+
return ' This DOM node was rendered by `' + name + '`.';
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return '';
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
var legacyPropsDescriptor;
|
|
74
|
+
if ('production' !== process.env.NODE_ENV) {
|
|
75
|
+
legacyPropsDescriptor = {
|
|
76
|
+
props: {
|
|
77
|
+
enumerable: false,
|
|
78
|
+
get: function () {
|
|
79
|
+
var component = this._reactInternalComponent;
|
|
80
|
+
'production' !== process.env.NODE_ENV ? warning(false, 'ReactDOMComponent: Do not access .props of a DOM node; instead, ' + 'recreate the props as `render` did originally or read the DOM ' + 'properties/attributes directly from this node (e.g., ' + 'this.refs.box.className).%s', getDeclarationErrorAddendum(component)) : undefined;
|
|
81
|
+
return component._currentElement.props;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function legacyGetDOMNode() {
|
|
88
|
+
if ('production' !== process.env.NODE_ENV) {
|
|
89
|
+
var component = this._reactInternalComponent;
|
|
90
|
+
'production' !== process.env.NODE_ENV ? warning(false, 'ReactDOMComponent: Do not access .getDOMNode() of a DOM node; ' + 'instead, use the node directly.%s', getDeclarationErrorAddendum(component)) : undefined;
|
|
91
|
+
}
|
|
92
|
+
return this;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function legacyIsMounted() {
|
|
96
|
+
var component = this._reactInternalComponent;
|
|
97
|
+
if ('production' !== process.env.NODE_ENV) {
|
|
98
|
+
'production' !== process.env.NODE_ENV ? warning(false, 'ReactDOMComponent: Do not access .isMounted() of a DOM node.%s', getDeclarationErrorAddendum(component)) : undefined;
|
|
99
|
+
}
|
|
100
|
+
return !!component;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function legacySetStateEtc() {
|
|
104
|
+
if ('production' !== process.env.NODE_ENV) {
|
|
105
|
+
var component = this._reactInternalComponent;
|
|
106
|
+
'production' !== process.env.NODE_ENV ? warning(false, 'ReactDOMComponent: Do not access .setState(), .replaceState(), or ' + '.forceUpdate() of a DOM node. This is a no-op.%s', getDeclarationErrorAddendum(component)) : undefined;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function legacySetProps(partialProps, callback) {
|
|
111
|
+
var component = this._reactInternalComponent;
|
|
112
|
+
if ('production' !== process.env.NODE_ENV) {
|
|
113
|
+
'production' !== process.env.NODE_ENV ? warning(false, 'ReactDOMComponent: Do not access .setProps() of a DOM node. ' + 'Instead, call React.render again at the top level.%s', getDeclarationErrorAddendum(component)) : undefined;
|
|
114
|
+
}
|
|
115
|
+
if (!component) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
ReactUpdateQueue.enqueueSetPropsInternal(component, partialProps);
|
|
119
|
+
if (callback) {
|
|
120
|
+
ReactUpdateQueue.enqueueCallbackInternal(component, callback);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function legacyReplaceProps(partialProps, callback) {
|
|
125
|
+
var component = this._reactInternalComponent;
|
|
126
|
+
if ('production' !== process.env.NODE_ENV) {
|
|
127
|
+
'production' !== process.env.NODE_ENV ? warning(false, 'ReactDOMComponent: Do not access .replaceProps() of a DOM node. ' + 'Instead, call React.render again at the top level.%s', getDeclarationErrorAddendum(component)) : undefined;
|
|
128
|
+
}
|
|
129
|
+
if (!component) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
ReactUpdateQueue.enqueueReplacePropsInternal(component, partialProps);
|
|
133
|
+
if (callback) {
|
|
134
|
+
ReactUpdateQueue.enqueueCallbackInternal(component, callback);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
var styleMutationWarning = {};
|
|
139
|
+
|
|
140
|
+
function checkAndWarnForMutatedStyle(style1, style2, component) {
|
|
141
|
+
if (style1 == null || style2 == null) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
if (shallowEqual(style1, style2)) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
var componentName = component._tag;
|
|
149
|
+
var owner = component._currentElement._owner;
|
|
150
|
+
var ownerName;
|
|
151
|
+
if (owner) {
|
|
152
|
+
ownerName = owner.getName();
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
var hash = ownerName + '|' + componentName;
|
|
156
|
+
|
|
157
|
+
if (styleMutationWarning.hasOwnProperty(hash)) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
styleMutationWarning[hash] = true;
|
|
162
|
+
|
|
163
|
+
'production' !== process.env.NODE_ENV ? 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 + '>', JSON.stringify(style1), JSON.stringify(style2)) : undefined;
|
|
164
|
+
}
|
|
165
|
+
|
|
45
166
|
/**
|
|
46
167
|
* Optionally injectable operations for mutating the DOM
|
|
47
168
|
*/
|
|
48
169
|
var BackendIDOperations = null;
|
|
49
170
|
|
|
50
171
|
/**
|
|
172
|
+
* @param {object} component
|
|
51
173
|
* @param {?object} props
|
|
52
174
|
*/
|
|
53
|
-
function assertValidProps(props) {
|
|
175
|
+
function assertValidProps(component, props) {
|
|
54
176
|
if (!props) {
|
|
55
177
|
return;
|
|
56
178
|
}
|
|
57
179
|
// Note the use of `==` which checks for null or undefined.
|
|
180
|
+
if ('production' !== process.env.NODE_ENV) {
|
|
181
|
+
if (voidElementTags[component._tag]) {
|
|
182
|
+
'production' !== process.env.NODE_ENV ? warning(props.children == null && props.dangerouslySetInnerHTML == null, '%s is a void element tag and must not have `children` or ' + 'use `props.dangerouslySetInnerHTML`.%s', component._tag, component._currentElement._owner ? ' Check the render method of ' + component._currentElement._owner.getName() + '.' : '') : undefined;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
58
185
|
if (props.dangerouslySetInnerHTML != null) {
|
|
59
|
-
(
|
|
60
|
-
|
|
61
|
-
'Can only set one of `children` or `props.dangerouslySetInnerHTML`.'
|
|
62
|
-
) : invariant(props.children == null));
|
|
63
|
-
("production" !== process.env.NODE_ENV ? invariant(
|
|
64
|
-
typeof props.dangerouslySetInnerHTML === 'object' &&
|
|
65
|
-
'__html' in props.dangerouslySetInnerHTML,
|
|
66
|
-
'`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' +
|
|
67
|
-
'Please visit https://fb.me/react-invariant-dangerously-set-inner-html ' +
|
|
68
|
-
'for more information.'
|
|
69
|
-
) : invariant(typeof props.dangerouslySetInnerHTML === 'object' &&
|
|
70
|
-
'__html' in props.dangerouslySetInnerHTML));
|
|
186
|
+
!(props.children == null) ? 'production' !== process.env.NODE_ENV ? invariant(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : invariant(false) : undefined;
|
|
187
|
+
!(typeof props.dangerouslySetInnerHTML === 'object' && '__html' in props.dangerouslySetInnerHTML) ? 'production' !== process.env.NODE_ENV ? invariant(false, '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' + 'Please visit https://fb.me/react-invariant-dangerously-set-inner-html ' + 'for more information.') : invariant(false) : undefined;
|
|
71
188
|
}
|
|
72
|
-
if (
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
'Directly setting property `innerHTML` is not permitted. ' +
|
|
76
|
-
'For more information, lookup documentation on `dangerouslySetInnerHTML`.'
|
|
77
|
-
) : null);
|
|
78
|
-
("production" !== process.env.NODE_ENV ? warning(
|
|
79
|
-
!props.contentEditable || props.children == null,
|
|
80
|
-
'A component is `contentEditable` and contains `children` managed by ' +
|
|
81
|
-
'React. It is now your responsibility to guarantee that none of ' +
|
|
82
|
-
'those nodes are unexpectedly modified or duplicated. This is ' +
|
|
83
|
-
'probably not intentional.'
|
|
84
|
-
) : null);
|
|
189
|
+
if ('production' !== process.env.NODE_ENV) {
|
|
190
|
+
'production' !== process.env.NODE_ENV ? warning(props.innerHTML == null, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.') : undefined;
|
|
191
|
+
'production' !== process.env.NODE_ENV ? warning(!props.contentEditable || props.children == null, 'A component is `contentEditable` and contains `children` managed by ' + 'React. It is now your responsibility to guarantee that none of ' + 'those nodes are unexpectedly modified or duplicated. This is ' + 'probably not intentional.') : undefined;
|
|
85
192
|
}
|
|
86
|
-
(
|
|
87
|
-
props.style == null || typeof props.style === 'object',
|
|
88
|
-
'The `style` prop expects a mapping from style properties to values, ' +
|
|
89
|
-
'not a string. For example, style={{marginRight: spacing + \'em\'}} when ' +
|
|
90
|
-
'using JSX.'
|
|
91
|
-
) : invariant(props.style == null || typeof props.style === 'object'));
|
|
193
|
+
!(props.style == null || typeof props.style === 'object') ? 'production' !== process.env.NODE_ENV ? 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.') : invariant(false) : undefined;
|
|
92
194
|
}
|
|
93
195
|
|
|
94
|
-
function
|
|
95
|
-
if (
|
|
196
|
+
function enqueuePutListener(id, registrationName, listener, transaction) {
|
|
197
|
+
if ('production' !== process.env.NODE_ENV) {
|
|
96
198
|
// IE8 has no API for event capturing and the `onScroll` event doesn't
|
|
97
199
|
// bubble.
|
|
98
|
-
|
|
99
|
-
registrationName !== 'onScroll' || isEventSupported('scroll', true),
|
|
100
|
-
'This browser doesn\'t support the `onScroll` event'
|
|
101
|
-
) : null);
|
|
200
|
+
'production' !== process.env.NODE_ENV ? warning(registrationName !== 'onScroll' || isEventSupported('scroll', true), 'This browser doesn\'t support the `onScroll` event') : undefined;
|
|
102
201
|
}
|
|
103
202
|
var container = ReactMount.findReactContainerForID(id);
|
|
104
203
|
if (container) {
|
|
105
|
-
var doc = container.nodeType === ELEMENT_NODE_TYPE ?
|
|
106
|
-
container.ownerDocument :
|
|
107
|
-
container;
|
|
204
|
+
var doc = container.nodeType === ELEMENT_NODE_TYPE ? container.ownerDocument : container;
|
|
108
205
|
listenTo(registrationName, doc);
|
|
109
206
|
}
|
|
110
|
-
transaction.
|
|
111
|
-
id,
|
|
112
|
-
registrationName,
|
|
113
|
-
listener
|
|
114
|
-
);
|
|
207
|
+
transaction.getReactMountReady().enqueue(putListener, {
|
|
208
|
+
id: id,
|
|
209
|
+
registrationName: registrationName,
|
|
210
|
+
listener: listener
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function putListener() {
|
|
215
|
+
var listenerToPut = this;
|
|
216
|
+
ReactBrowserEventEmitter.putListener(listenerToPut.id, listenerToPut.registrationName, listenerToPut.listener);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function trapBubbledEventsLocal() {
|
|
220
|
+
var inst = this;
|
|
221
|
+
// If a component renders to null or if another component fatals and causes
|
|
222
|
+
// the state of the tree to be corrupted, `node` here can be null.
|
|
223
|
+
!inst._rootNodeID ? 'production' !== process.env.NODE_ENV ? invariant(false, 'Must be mounted to trap events') : invariant(false) : undefined;
|
|
224
|
+
var node = ReactMount.getNode(inst._rootNodeID);
|
|
225
|
+
!node ? 'production' !== process.env.NODE_ENV ? invariant(false, 'trapBubbledEvent(...): Requires node to be rendered.') : invariant(false) : undefined;
|
|
226
|
+
|
|
227
|
+
switch (inst._tag) {
|
|
228
|
+
case 'iframe':
|
|
229
|
+
inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topLoad, 'load', node)];
|
|
230
|
+
break;
|
|
231
|
+
case 'img':
|
|
232
|
+
inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topError, 'error', node), ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topLoad, 'load', node)];
|
|
233
|
+
break;
|
|
234
|
+
case 'form':
|
|
235
|
+
inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topReset, 'reset', node), ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topSubmit, 'submit', node)];
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function postUpdateSelectWrapper() {
|
|
241
|
+
ReactDOMSelect.postUpdateWrapper(this);
|
|
115
242
|
}
|
|
116
243
|
|
|
117
244
|
// For HTML, certain tags should omit their close tag. We keep a whitelist for
|
|
@@ -133,24 +260,50 @@ var omittedCloseTags = {
|
|
|
133
260
|
'source': true,
|
|
134
261
|
'track': true,
|
|
135
262
|
'wbr': true
|
|
136
|
-
// NOTE: menuitem's close tag should be omitted, but that causes problems.
|
|
137
263
|
};
|
|
138
264
|
|
|
139
|
-
|
|
265
|
+
var newlineEatingTags = {
|
|
266
|
+
'listing': true,
|
|
267
|
+
'pre': true,
|
|
268
|
+
'textarea': true
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
// For HTML, certain tags cannot have children. This has the same purpose as
|
|
272
|
+
// `omittedCloseTags` except that `menuitem` should still have its closing tag.
|
|
273
|
+
|
|
274
|
+
var voidElementTags = assign({
|
|
275
|
+
'menuitem': true
|
|
276
|
+
}, omittedCloseTags);
|
|
277
|
+
|
|
278
|
+
// We accept any tag to be rendered but since this gets injected into arbitrary
|
|
140
279
|
// HTML, we want to make sure that it's a safe tag.
|
|
141
280
|
// http://www.w3.org/TR/REC-xml/#NT-Name
|
|
142
281
|
|
|
143
282
|
var VALID_TAG_REGEX = /^[a-zA-Z][a-zA-Z:_\.\-\d]*$/; // Simplified subset
|
|
144
283
|
var validatedTagCache = {};
|
|
145
|
-
var hasOwnProperty = {}.hasOwnProperty;
|
|
284
|
+
var hasOwnProperty = ({}).hasOwnProperty;
|
|
146
285
|
|
|
147
286
|
function validateDangerousTag(tag) {
|
|
148
287
|
if (!hasOwnProperty.call(validatedTagCache, tag)) {
|
|
149
|
-
(
|
|
288
|
+
!VALID_TAG_REGEX.test(tag) ? 'production' !== process.env.NODE_ENV ? invariant(false, 'Invalid tag: %s', tag) : invariant(false) : undefined;
|
|
150
289
|
validatedTagCache[tag] = true;
|
|
151
290
|
}
|
|
152
291
|
}
|
|
153
292
|
|
|
293
|
+
function processChildContext(context, inst) {
|
|
294
|
+
if ('production' !== process.env.NODE_ENV) {
|
|
295
|
+
// Pass down our tag name to child components for validation purposes
|
|
296
|
+
context = assign({}, context);
|
|
297
|
+
var info = context[validateDOMNesting.ancestorInfoContextKey];
|
|
298
|
+
context[validateDOMNesting.ancestorInfoContextKey] = validateDOMNesting.updatedAncestorInfo(info, inst._tag, inst);
|
|
299
|
+
}
|
|
300
|
+
return context;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
function isCustomComponent(tagName, props) {
|
|
304
|
+
return tagName.indexOf('-') >= 0 || props.is != null;
|
|
305
|
+
}
|
|
306
|
+
|
|
154
307
|
/**
|
|
155
308
|
* Creates a new React class that is idempotent and capable of containing other
|
|
156
309
|
* React components. It accepts event listeners and DOM properties that are
|
|
@@ -167,17 +320,21 @@ function validateDangerousTag(tag) {
|
|
|
167
320
|
*/
|
|
168
321
|
function ReactDOMComponent(tag) {
|
|
169
322
|
validateDangerousTag(tag);
|
|
170
|
-
this._tag = tag;
|
|
323
|
+
this._tag = tag.toLowerCase();
|
|
171
324
|
this._renderedChildren = null;
|
|
325
|
+
this._previousStyle = null;
|
|
172
326
|
this._previousStyleCopy = null;
|
|
173
327
|
this._rootNodeID = null;
|
|
328
|
+
this._wrapperState = null;
|
|
329
|
+
this._topLevelWrapper = null;
|
|
330
|
+
this._nodeWithLegacyProperties = null;
|
|
174
331
|
}
|
|
175
332
|
|
|
176
333
|
ReactDOMComponent.displayName = 'ReactDOMComponent';
|
|
177
334
|
|
|
178
335
|
ReactDOMComponent.Mixin = {
|
|
179
336
|
|
|
180
|
-
construct: function(element) {
|
|
337
|
+
construct: function (element) {
|
|
181
338
|
this._currentElement = element;
|
|
182
339
|
},
|
|
183
340
|
|
|
@@ -188,17 +345,70 @@ ReactDOMComponent.Mixin = {
|
|
|
188
345
|
* @internal
|
|
189
346
|
* @param {string} rootID The root DOM ID for this node.
|
|
190
347
|
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
|
|
348
|
+
* @param {object} context
|
|
191
349
|
* @return {string} The computed markup.
|
|
192
350
|
*/
|
|
193
|
-
mountComponent: function(rootID, transaction, context) {
|
|
351
|
+
mountComponent: function (rootID, transaction, context) {
|
|
194
352
|
this._rootNodeID = rootID;
|
|
195
|
-
|
|
196
|
-
var
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
353
|
+
|
|
354
|
+
var props = this._currentElement.props;
|
|
355
|
+
|
|
356
|
+
switch (this._tag) {
|
|
357
|
+
case 'iframe':
|
|
358
|
+
case 'img':
|
|
359
|
+
case 'form':
|
|
360
|
+
this._wrapperState = {
|
|
361
|
+
listeners: null
|
|
362
|
+
};
|
|
363
|
+
transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this);
|
|
364
|
+
break;
|
|
365
|
+
case 'button':
|
|
366
|
+
props = ReactDOMButton.getNativeProps(this, props, context);
|
|
367
|
+
break;
|
|
368
|
+
case 'input':
|
|
369
|
+
ReactDOMInput.mountWrapper(this, props, context);
|
|
370
|
+
props = ReactDOMInput.getNativeProps(this, props, context);
|
|
371
|
+
break;
|
|
372
|
+
case 'option':
|
|
373
|
+
ReactDOMOption.mountWrapper(this, props, context);
|
|
374
|
+
props = ReactDOMOption.getNativeProps(this, props, context);
|
|
375
|
+
break;
|
|
376
|
+
case 'select':
|
|
377
|
+
ReactDOMSelect.mountWrapper(this, props, context);
|
|
378
|
+
props = ReactDOMSelect.getNativeProps(this, props, context);
|
|
379
|
+
context = ReactDOMSelect.processChildContext(this, props, context);
|
|
380
|
+
break;
|
|
381
|
+
case 'textarea':
|
|
382
|
+
ReactDOMTextarea.mountWrapper(this, props, context);
|
|
383
|
+
props = ReactDOMTextarea.getNativeProps(this, props, context);
|
|
384
|
+
break;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
assertValidProps(this, props);
|
|
388
|
+
if ('production' !== process.env.NODE_ENV) {
|
|
389
|
+
if (context[validateDOMNesting.ancestorInfoContextKey]) {
|
|
390
|
+
validateDOMNesting(this._tag, this, context[validateDOMNesting.ancestorInfoContextKey]);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
var tagOpen = this._createOpenTagMarkupAndPutListeners(transaction, props);
|
|
395
|
+
var tagContent = this._createContentMarkup(transaction, props, context);
|
|
396
|
+
|
|
397
|
+
switch (this._tag) {
|
|
398
|
+
case 'button':
|
|
399
|
+
case 'input':
|
|
400
|
+
case 'select':
|
|
401
|
+
case 'textarea':
|
|
402
|
+
if (props.autoFocus) {
|
|
403
|
+
transaction.getReactMountReady().enqueue(AutoFocusUtils.focusDOMComponent, this);
|
|
404
|
+
}
|
|
405
|
+
break;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
if (!tagContent && omittedCloseTags[this._tag]) {
|
|
409
|
+
return tagOpen + '/>';
|
|
410
|
+
}
|
|
411
|
+
return tagOpen + '>' + tagContent + '</' + this._currentElement.type + '>';
|
|
202
412
|
},
|
|
203
413
|
|
|
204
414
|
/**
|
|
@@ -211,11 +421,11 @@ ReactDOMComponent.Mixin = {
|
|
|
211
421
|
*
|
|
212
422
|
* @private
|
|
213
423
|
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
|
|
424
|
+
* @param {object} props
|
|
214
425
|
* @return {string} Markup of opening tag.
|
|
215
426
|
*/
|
|
216
|
-
_createOpenTagMarkupAndPutListeners: function(transaction) {
|
|
217
|
-
var
|
|
218
|
-
var ret = '<' + this._tag;
|
|
427
|
+
_createOpenTagMarkupAndPutListeners: function (transaction, props) {
|
|
428
|
+
var ret = '<' + this._currentElement.type;
|
|
219
429
|
|
|
220
430
|
for (var propKey in props) {
|
|
221
431
|
if (!props.hasOwnProperty(propKey)) {
|
|
@@ -226,16 +436,24 @@ ReactDOMComponent.Mixin = {
|
|
|
226
436
|
continue;
|
|
227
437
|
}
|
|
228
438
|
if (registrationNameModules.hasOwnProperty(propKey)) {
|
|
229
|
-
|
|
439
|
+
enqueuePutListener(this._rootNodeID, propKey, propValue, transaction);
|
|
230
440
|
} else {
|
|
231
441
|
if (propKey === STYLE) {
|
|
232
442
|
if (propValue) {
|
|
443
|
+
if ('production' !== process.env.NODE_ENV) {
|
|
444
|
+
// See `_updateDOMProperties`. style block
|
|
445
|
+
this._previousStyle = propValue;
|
|
446
|
+
}
|
|
233
447
|
propValue = this._previousStyleCopy = assign({}, props.style);
|
|
234
448
|
}
|
|
235
449
|
propValue = CSSPropertyOperations.createMarkupForStyles(propValue);
|
|
236
450
|
}
|
|
237
|
-
var markup =
|
|
238
|
-
|
|
451
|
+
var markup = null;
|
|
452
|
+
if (this._tag != null && isCustomComponent(this._tag, props)) {
|
|
453
|
+
markup = DOMPropertyOperations.createMarkupForCustomAttribute(propKey, propValue);
|
|
454
|
+
} else {
|
|
455
|
+
markup = DOMPropertyOperations.createMarkupForProperty(propKey, propValue);
|
|
456
|
+
}
|
|
239
457
|
if (markup) {
|
|
240
458
|
ret += ' ' + markup;
|
|
241
459
|
}
|
|
@@ -245,11 +463,11 @@ ReactDOMComponent.Mixin = {
|
|
|
245
463
|
// For static pages, no need to put React ID and checksum. Saves lots of
|
|
246
464
|
// bytes.
|
|
247
465
|
if (transaction.renderToStaticMarkup) {
|
|
248
|
-
return ret
|
|
466
|
+
return ret;
|
|
249
467
|
}
|
|
250
468
|
|
|
251
469
|
var markupForID = DOMPropertyOperations.createMarkupForID(this._rootNodeID);
|
|
252
|
-
return ret + ' ' + markupForID
|
|
470
|
+
return ret + ' ' + markupForID;
|
|
253
471
|
},
|
|
254
472
|
|
|
255
473
|
/**
|
|
@@ -257,47 +475,56 @@ ReactDOMComponent.Mixin = {
|
|
|
257
475
|
*
|
|
258
476
|
* @private
|
|
259
477
|
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
|
|
478
|
+
* @param {object} props
|
|
260
479
|
* @param {object} context
|
|
261
480
|
* @return {string} Content markup.
|
|
262
481
|
*/
|
|
263
|
-
_createContentMarkup: function(transaction, context) {
|
|
264
|
-
var
|
|
265
|
-
if (this._tag === 'listing' ||
|
|
266
|
-
this._tag === 'pre' ||
|
|
267
|
-
this._tag === 'textarea') {
|
|
268
|
-
// Add an initial newline because browsers ignore the first newline in
|
|
269
|
-
// a <listing>, <pre>, or <textarea> as an "authoring convenience" -- see
|
|
270
|
-
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody.
|
|
271
|
-
prefix = '\n';
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
var props = this._currentElement.props;
|
|
482
|
+
_createContentMarkup: function (transaction, props, context) {
|
|
483
|
+
var ret = '';
|
|
275
484
|
|
|
276
485
|
// Intentional use of != to avoid catching zero/false.
|
|
277
486
|
var innerHTML = props.dangerouslySetInnerHTML;
|
|
278
487
|
if (innerHTML != null) {
|
|
279
488
|
if (innerHTML.__html != null) {
|
|
280
|
-
|
|
489
|
+
ret = innerHTML.__html;
|
|
281
490
|
}
|
|
282
491
|
} else {
|
|
283
|
-
var contentToUse =
|
|
284
|
-
CONTENT_TYPES[typeof props.children] ? props.children : null;
|
|
492
|
+
var contentToUse = CONTENT_TYPES[typeof props.children] ? props.children : null;
|
|
285
493
|
var childrenToUse = contentToUse != null ? null : props.children;
|
|
286
494
|
if (contentToUse != null) {
|
|
287
|
-
|
|
495
|
+
// TODO: Validate that text is allowed as a child of this node
|
|
496
|
+
ret = escapeTextContentForBrowser(contentToUse);
|
|
288
497
|
} else if (childrenToUse != null) {
|
|
289
|
-
var mountImages = this.mountChildren(
|
|
290
|
-
|
|
291
|
-
transaction,
|
|
292
|
-
context
|
|
293
|
-
);
|
|
294
|
-
return prefix + mountImages.join('');
|
|
498
|
+
var mountImages = this.mountChildren(childrenToUse, transaction, processChildContext(context, this));
|
|
499
|
+
ret = mountImages.join('');
|
|
295
500
|
}
|
|
296
501
|
}
|
|
297
|
-
|
|
502
|
+
if (newlineEatingTags[this._tag] && ret.charAt(0) === '\n') {
|
|
503
|
+
// text/html ignores the first character in these tags if it's a newline
|
|
504
|
+
// Prefer to break application/xml over text/html (for now) by adding
|
|
505
|
+
// a newline specifically to get eaten by the parser. (Alternately for
|
|
506
|
+
// textareas, replacing "^\n" with "\r\n" doesn't get eaten, and the first
|
|
507
|
+
// \r is normalized out by HTMLTextAreaElement#value.)
|
|
508
|
+
// See: <http://www.w3.org/TR/html-polyglot/#newlines-in-textarea-and-pre>
|
|
509
|
+
// See: <http://www.w3.org/TR/html5/syntax.html#element-restrictions>
|
|
510
|
+
// See: <http://www.w3.org/TR/html5/syntax.html#newlines>
|
|
511
|
+
// See: Parsing of "textarea" "listing" and "pre" elements
|
|
512
|
+
// from <http://www.w3.org/TR/html5/syntax.html#parsing-main-inbody>
|
|
513
|
+
return '\n' + ret;
|
|
514
|
+
} else {
|
|
515
|
+
return ret;
|
|
516
|
+
}
|
|
298
517
|
},
|
|
299
518
|
|
|
300
|
-
|
|
519
|
+
/**
|
|
520
|
+
* Receives a next element and updates the component.
|
|
521
|
+
*
|
|
522
|
+
* @internal
|
|
523
|
+
* @param {ReactElement} nextElement
|
|
524
|
+
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
|
|
525
|
+
* @param {object} context
|
|
526
|
+
*/
|
|
527
|
+
receiveComponent: function (nextElement, transaction, context) {
|
|
301
528
|
var prevElement = this._currentElement;
|
|
302
529
|
this._currentElement = nextElement;
|
|
303
530
|
this.updateComponent(transaction, prevElement, nextElement, context);
|
|
@@ -313,10 +540,48 @@ ReactDOMComponent.Mixin = {
|
|
|
313
540
|
* @internal
|
|
314
541
|
* @overridable
|
|
315
542
|
*/
|
|
316
|
-
updateComponent: function(transaction, prevElement, nextElement, context) {
|
|
317
|
-
|
|
318
|
-
this.
|
|
319
|
-
|
|
543
|
+
updateComponent: function (transaction, prevElement, nextElement, context) {
|
|
544
|
+
var lastProps = prevElement.props;
|
|
545
|
+
var nextProps = this._currentElement.props;
|
|
546
|
+
|
|
547
|
+
switch (this._tag) {
|
|
548
|
+
case 'button':
|
|
549
|
+
lastProps = ReactDOMButton.getNativeProps(this, lastProps);
|
|
550
|
+
nextProps = ReactDOMButton.getNativeProps(this, nextProps);
|
|
551
|
+
break;
|
|
552
|
+
case 'input':
|
|
553
|
+
ReactDOMInput.updateWrapper(this);
|
|
554
|
+
lastProps = ReactDOMInput.getNativeProps(this, lastProps);
|
|
555
|
+
nextProps = ReactDOMInput.getNativeProps(this, nextProps);
|
|
556
|
+
break;
|
|
557
|
+
case 'option':
|
|
558
|
+
lastProps = ReactDOMOption.getNativeProps(this, lastProps);
|
|
559
|
+
nextProps = ReactDOMOption.getNativeProps(this, nextProps);
|
|
560
|
+
break;
|
|
561
|
+
case 'select':
|
|
562
|
+
lastProps = ReactDOMSelect.getNativeProps(this, lastProps);
|
|
563
|
+
nextProps = ReactDOMSelect.getNativeProps(this, nextProps);
|
|
564
|
+
break;
|
|
565
|
+
case 'textarea':
|
|
566
|
+
ReactDOMTextarea.updateWrapper(this);
|
|
567
|
+
lastProps = ReactDOMTextarea.getNativeProps(this, lastProps);
|
|
568
|
+
nextProps = ReactDOMTextarea.getNativeProps(this, nextProps);
|
|
569
|
+
break;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
assertValidProps(this, nextProps);
|
|
573
|
+
this._updateDOMProperties(lastProps, nextProps, transaction);
|
|
574
|
+
this._updateDOMChildren(lastProps, nextProps, transaction, processChildContext(context, this));
|
|
575
|
+
|
|
576
|
+
if (!canDefineProperty && this._nodeWithLegacyProperties) {
|
|
577
|
+
this._nodeWithLegacyProperties.props = nextProps;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
if (this._tag === 'select') {
|
|
581
|
+
// <select> value update needs to occur after <option> children
|
|
582
|
+
// reconciliation
|
|
583
|
+
transaction.getReactMountReady().enqueue(postUpdateSelectWrapper, this);
|
|
584
|
+
}
|
|
320
585
|
},
|
|
321
586
|
|
|
322
587
|
/**
|
|
@@ -332,16 +597,15 @@ ReactDOMComponent.Mixin = {
|
|
|
332
597
|
*
|
|
333
598
|
* @private
|
|
334
599
|
* @param {object} lastProps
|
|
600
|
+
* @param {object} nextProps
|
|
335
601
|
* @param {ReactReconcileTransaction} transaction
|
|
336
602
|
*/
|
|
337
|
-
_updateDOMProperties: function(lastProps, transaction) {
|
|
338
|
-
var nextProps = this._currentElement.props;
|
|
603
|
+
_updateDOMProperties: function (lastProps, nextProps, transaction) {
|
|
339
604
|
var propKey;
|
|
340
605
|
var styleName;
|
|
341
606
|
var styleUpdates;
|
|
342
607
|
for (propKey in lastProps) {
|
|
343
|
-
if (nextProps.hasOwnProperty(propKey) ||
|
|
344
|
-
!lastProps.hasOwnProperty(propKey)) {
|
|
608
|
+
if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey)) {
|
|
345
609
|
continue;
|
|
346
610
|
}
|
|
347
611
|
if (propKey === STYLE) {
|
|
@@ -354,26 +618,28 @@ ReactDOMComponent.Mixin = {
|
|
|
354
618
|
}
|
|
355
619
|
this._previousStyleCopy = null;
|
|
356
620
|
} else if (registrationNameModules.hasOwnProperty(propKey)) {
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
);
|
|
621
|
+
if (lastProps[propKey]) {
|
|
622
|
+
// Only call deleteListener if there was a listener previously or
|
|
623
|
+
// else willDeleteListener gets called when there wasn't actually a
|
|
624
|
+
// listener (e.g., onClick={null})
|
|
625
|
+
deleteListener(this._rootNodeID, propKey);
|
|
626
|
+
}
|
|
627
|
+
} else if (DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) {
|
|
628
|
+
BackendIDOperations.deletePropertyByID(this._rootNodeID, propKey);
|
|
365
629
|
}
|
|
366
630
|
}
|
|
367
631
|
for (propKey in nextProps) {
|
|
368
632
|
var nextProp = nextProps[propKey];
|
|
369
|
-
var lastProp = propKey === STYLE ?
|
|
370
|
-
this._previousStyleCopy :
|
|
371
|
-
lastProps[propKey];
|
|
633
|
+
var lastProp = propKey === STYLE ? this._previousStyleCopy : lastProps[propKey];
|
|
372
634
|
if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp) {
|
|
373
635
|
continue;
|
|
374
636
|
}
|
|
375
637
|
if (propKey === STYLE) {
|
|
376
638
|
if (nextProp) {
|
|
639
|
+
if ('production' !== process.env.NODE_ENV) {
|
|
640
|
+
checkAndWarnForMutatedStyle(this._previousStyleCopy, this._previousStyle, this);
|
|
641
|
+
this._previousStyle = nextProp;
|
|
642
|
+
}
|
|
377
643
|
nextProp = this._previousStyleCopy = assign({}, nextProp);
|
|
378
644
|
} else {
|
|
379
645
|
this._previousStyleCopy = null;
|
|
@@ -381,16 +647,14 @@ ReactDOMComponent.Mixin = {
|
|
|
381
647
|
if (lastProp) {
|
|
382
648
|
// Unset styles on `lastProp` but not on `nextProp`.
|
|
383
649
|
for (styleName in lastProp) {
|
|
384
|
-
if (lastProp.hasOwnProperty(styleName) &&
|
|
385
|
-
(!nextProp || !nextProp.hasOwnProperty(styleName))) {
|
|
650
|
+
if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {
|
|
386
651
|
styleUpdates = styleUpdates || {};
|
|
387
652
|
styleUpdates[styleName] = '';
|
|
388
653
|
}
|
|
389
654
|
}
|
|
390
655
|
// Update styles that changed since `lastProp`.
|
|
391
656
|
for (styleName in nextProp) {
|
|
392
|
-
if (nextProp.hasOwnProperty(styleName) &&
|
|
393
|
-
lastProp[styleName] !== nextProp[styleName]) {
|
|
657
|
+
if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {
|
|
394
658
|
styleUpdates = styleUpdates || {};
|
|
395
659
|
styleUpdates[styleName] = nextProp[styleName];
|
|
396
660
|
}
|
|
@@ -400,22 +664,19 @@ ReactDOMComponent.Mixin = {
|
|
|
400
664
|
styleUpdates = nextProp;
|
|
401
665
|
}
|
|
402
666
|
} else if (registrationNameModules.hasOwnProperty(propKey)) {
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
);
|
|
667
|
+
if (nextProp) {
|
|
668
|
+
enqueuePutListener(this._rootNodeID, propKey, nextProp, transaction);
|
|
669
|
+
} else if (lastProp) {
|
|
670
|
+
deleteListener(this._rootNodeID, propKey);
|
|
671
|
+
}
|
|
672
|
+
} else if (isCustomComponent(this._tag, nextProps)) {
|
|
673
|
+
BackendIDOperations.updateAttributeByID(this._rootNodeID, propKey, nextProp);
|
|
674
|
+
} else if (DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) {
|
|
675
|
+
BackendIDOperations.updatePropertyByID(this._rootNodeID, propKey, nextProp);
|
|
412
676
|
}
|
|
413
677
|
}
|
|
414
678
|
if (styleUpdates) {
|
|
415
|
-
BackendIDOperations.updateStylesByID(
|
|
416
|
-
this._rootNodeID,
|
|
417
|
-
styleUpdates
|
|
418
|
-
);
|
|
679
|
+
BackendIDOperations.updateStylesByID(this._rootNodeID, styleUpdates);
|
|
419
680
|
}
|
|
420
681
|
},
|
|
421
682
|
|
|
@@ -424,22 +685,16 @@ ReactDOMComponent.Mixin = {
|
|
|
424
685
|
* children content.
|
|
425
686
|
*
|
|
426
687
|
* @param {object} lastProps
|
|
688
|
+
* @param {object} nextProps
|
|
427
689
|
* @param {ReactReconcileTransaction} transaction
|
|
690
|
+
* @param {object} context
|
|
428
691
|
*/
|
|
429
|
-
_updateDOMChildren: function(lastProps, transaction, context) {
|
|
430
|
-
var
|
|
431
|
-
|
|
432
|
-
var lastContent =
|
|
433
|
-
CONTENT_TYPES[typeof lastProps.children] ? lastProps.children : null;
|
|
434
|
-
var nextContent =
|
|
435
|
-
CONTENT_TYPES[typeof nextProps.children] ? nextProps.children : null;
|
|
692
|
+
_updateDOMChildren: function (lastProps, nextProps, transaction, context) {
|
|
693
|
+
var lastContent = CONTENT_TYPES[typeof lastProps.children] ? lastProps.children : null;
|
|
694
|
+
var nextContent = CONTENT_TYPES[typeof nextProps.children] ? nextProps.children : null;
|
|
436
695
|
|
|
437
|
-
var lastHtml =
|
|
438
|
-
|
|
439
|
-
lastProps.dangerouslySetInnerHTML.__html;
|
|
440
|
-
var nextHtml =
|
|
441
|
-
nextProps.dangerouslySetInnerHTML &&
|
|
442
|
-
nextProps.dangerouslySetInnerHTML.__html;
|
|
696
|
+
var lastHtml = lastProps.dangerouslySetInnerHTML && lastProps.dangerouslySetInnerHTML.__html;
|
|
697
|
+
var nextHtml = nextProps.dangerouslySetInnerHTML && nextProps.dangerouslySetInnerHTML.__html;
|
|
443
698
|
|
|
444
699
|
// Note the use of `!=` which checks for null or undefined.
|
|
445
700
|
var lastChildren = lastContent != null ? null : lastProps.children;
|
|
@@ -461,10 +716,7 @@ ReactDOMComponent.Mixin = {
|
|
|
461
716
|
}
|
|
462
717
|
} else if (nextHtml != null) {
|
|
463
718
|
if (lastHtml !== nextHtml) {
|
|
464
|
-
BackendIDOperations.updateInnerHTMLByID(
|
|
465
|
-
this._rootNodeID,
|
|
466
|
-
nextHtml
|
|
467
|
-
);
|
|
719
|
+
BackendIDOperations.updateInnerHTMLByID(this._rootNodeID, nextHtml);
|
|
468
720
|
}
|
|
469
721
|
} else if (nextChildren != null) {
|
|
470
722
|
this.updateChildren(nextChildren, transaction, context);
|
|
@@ -477,11 +729,74 @@ ReactDOMComponent.Mixin = {
|
|
|
477
729
|
*
|
|
478
730
|
* @internal
|
|
479
731
|
*/
|
|
480
|
-
unmountComponent: function() {
|
|
732
|
+
unmountComponent: function () {
|
|
733
|
+
switch (this._tag) {
|
|
734
|
+
case 'iframe':
|
|
735
|
+
case 'img':
|
|
736
|
+
case 'form':
|
|
737
|
+
var listeners = this._wrapperState.listeners;
|
|
738
|
+
if (listeners) {
|
|
739
|
+
for (var i = 0; i < listeners.length; i++) {
|
|
740
|
+
listeners[i].remove();
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
break;
|
|
744
|
+
case 'input':
|
|
745
|
+
ReactDOMInput.unmountWrapper(this);
|
|
746
|
+
break;
|
|
747
|
+
case 'html':
|
|
748
|
+
case 'head':
|
|
749
|
+
case 'body':
|
|
750
|
+
/**
|
|
751
|
+
* Components like <html> <head> and <body> can't be removed or added
|
|
752
|
+
* easily in a cross-browser way, however it's valuable to be able to
|
|
753
|
+
* take advantage of React's reconciliation for styling and <title>
|
|
754
|
+
* management. So we just document it and throw in dangerous cases.
|
|
755
|
+
*/
|
|
756
|
+
!false ? 'production' !== process.env.NODE_ENV ? 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) : invariant(false) : undefined;
|
|
757
|
+
break;
|
|
758
|
+
}
|
|
759
|
+
|
|
481
760
|
this.unmountChildren();
|
|
482
761
|
ReactBrowserEventEmitter.deleteAllListeners(this._rootNodeID);
|
|
483
762
|
ReactComponentBrowserEnvironment.unmountIDFromEnvironment(this._rootNodeID);
|
|
484
763
|
this._rootNodeID = null;
|
|
764
|
+
this._wrapperState = null;
|
|
765
|
+
if (this._nodeWithLegacyProperties) {
|
|
766
|
+
var node = this._nodeWithLegacyProperties;
|
|
767
|
+
node._reactInternalComponent = null;
|
|
768
|
+
this._nodeWithLegacyProperties = null;
|
|
769
|
+
}
|
|
770
|
+
},
|
|
771
|
+
|
|
772
|
+
getPublicInstance: function () {
|
|
773
|
+
if (!this._nodeWithLegacyProperties) {
|
|
774
|
+
var node = ReactMount.getNode(this._rootNodeID);
|
|
775
|
+
|
|
776
|
+
node._reactInternalComponent = this;
|
|
777
|
+
node.getDOMNode = legacyGetDOMNode;
|
|
778
|
+
node.isMounted = legacyIsMounted;
|
|
779
|
+
node.setState = legacySetStateEtc;
|
|
780
|
+
node.replaceState = legacySetStateEtc;
|
|
781
|
+
node.forceUpdate = legacySetStateEtc;
|
|
782
|
+
node.setProps = legacySetProps;
|
|
783
|
+
node.replaceProps = legacyReplaceProps;
|
|
784
|
+
|
|
785
|
+
if ('production' !== process.env.NODE_ENV) {
|
|
786
|
+
if (canDefineProperty) {
|
|
787
|
+
Object.defineProperties(node, legacyPropsDescriptor);
|
|
788
|
+
} else {
|
|
789
|
+
// updateComponent will update this property on subsequent renders
|
|
790
|
+
node.props = this._currentElement.props;
|
|
791
|
+
}
|
|
792
|
+
} else {
|
|
793
|
+
// updateComponent will update this property on subsequent renders
|
|
794
|
+
node.props = this._currentElement.props;
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
this._nodeWithLegacyProperties = node;
|
|
798
|
+
}
|
|
799
|
+
return this._nodeWithLegacyProperties;
|
|
485
800
|
}
|
|
486
801
|
|
|
487
802
|
};
|
|
@@ -491,16 +806,13 @@ ReactPerf.measureMethods(ReactDOMComponent, 'ReactDOMComponent', {
|
|
|
491
806
|
updateComponent: 'updateComponent'
|
|
492
807
|
});
|
|
493
808
|
|
|
494
|
-
assign(
|
|
495
|
-
ReactDOMComponent.prototype,
|
|
496
|
-
ReactDOMComponent.Mixin,
|
|
497
|
-
ReactMultiChild.Mixin
|
|
498
|
-
);
|
|
809
|
+
assign(ReactDOMComponent.prototype, ReactDOMComponent.Mixin, ReactMultiChild.Mixin);
|
|
499
810
|
|
|
500
811
|
ReactDOMComponent.injection = {
|
|
501
|
-
injectIDOperations: function(IDOperations) {
|
|
812
|
+
injectIDOperations: function (IDOperations) {
|
|
502
813
|
ReactDOMComponent.BackendIDOperations = BackendIDOperations = IDOperations;
|
|
503
814
|
}
|
|
504
815
|
};
|
|
505
816
|
|
|
506
817
|
module.exports = ReactDOMComponent;
|
|
818
|
+
// NOTE: menuitem's close tag should be omitted, but that causes problems.
|