react 0.14.0-alpha2 → 0.14.0-beta3
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 +6 -3
- package/dist/JSXTransformer.js +634 -274
- package/dist/react-with-addons.js +5350 -4954
- package/dist/react-with-addons.min.js +6 -6
- package/dist/react.js +4777 -4408
- package/dist/react.min.js +6 -5
- package/lib/{AutoFocusMixin.js → AutoFocusUtils.js} +15 -5
- package/lib/BeforeInputEventPlugin.js +13 -13
- package/lib/CSSProperty.js +3 -0
- package/lib/CSSPropertyOperations.js +13 -13
- package/lib/CallbackQueue.js +4 -4
- package/lib/ChangeEventPlugin.js +16 -14
- package/lib/DOMChildrenOperations.js +10 -6
- package/lib/DOMProperty.js +82 -117
- package/lib/DOMPropertyOperations.js +78 -33
- package/lib/Danger.js +14 -14
- package/lib/DefaultEventPluginOrder.js +2 -2
- package/lib/EnterLeaveEventPlugin.js +8 -8
- package/lib/EventConstants.js +23 -1
- package/lib/EventPluginHub.js +13 -13
- package/lib/EventPluginRegistry.js +8 -8
- package/lib/EventPluginUtils.js +17 -17
- package/lib/EventPropagators.js +7 -7
- package/lib/FallbackCompositionState.js +3 -3
- package/lib/HTMLDOMPropertyConfig.js +13 -3
- package/lib/LinkedStateMixin.js +2 -2
- package/lib/LinkedValueUtils.js +50 -38
- package/lib/MetaMatchers.js +118 -0
- package/lib/OrderedMap.js +453 -0
- package/lib/PooledClass.js +14 -2
- package/lib/React.js +6 -6
- package/lib/ReactBrowserComponentMixin.js +4 -4
- package/lib/ReactBrowserEventEmitter.js +30 -7
- package/lib/ReactCSSTransitionGroup.js +16 -5
- package/lib/ReactCSSTransitionGroupChild.js +20 -11
- package/lib/ReactChildReconciler.js +25 -18
- package/lib/ReactChildren.js +9 -9
- package/lib/ReactClass.js +65 -83
- package/lib/ReactComponent.js +22 -17
- package/lib/ReactComponentBrowserEnvironment.js +2 -2
- package/lib/ReactComponentEnvironment.js +2 -2
- package/lib/ReactComponentWithPureRenderMixin.js +3 -3
- package/lib/ReactCompositeComponent.js +80 -111
- package/lib/ReactDOM.js +72 -158
- package/lib/ReactDOMButton.js +15 -26
- package/lib/ReactDOMComponent.js +378 -56
- package/lib/ReactDOMFactories.js +177 -0
- package/lib/ReactDOMIDOperations.js +23 -23
- package/lib/ReactDOMInput.js +83 -99
- package/lib/ReactDOMOption.js +25 -45
- package/lib/ReactDOMSelect.js +88 -98
- package/lib/ReactDOMSelection.js +3 -3
- package/lib/ReactDOMServer.js +2 -2
- package/lib/ReactDOMTextComponent.js +11 -11
- package/lib/ReactDOMTextarea.js +48 -61
- package/lib/ReactDefaultBatchingStrategy.js +4 -4
- package/lib/ReactDefaultInjection.js +24 -71
- package/lib/ReactDefaultPerf.js +7 -7
- package/lib/ReactDefaultPerfAnalysis.js +6 -9
- package/lib/ReactElement.js +22 -83
- package/lib/ReactElementValidator.js +48 -117
- package/lib/ReactEmptyComponent.js +4 -4
- package/lib/ReactErrorUtils.js +1 -1
- package/lib/ReactEventEmitterMixin.js +3 -4
- package/lib/ReactEventListener.js +57 -12
- package/lib/ReactFragment.js +22 -17
- package/lib/ReactInjection.js +11 -11
- package/lib/ReactInputSelection.js +8 -7
- package/lib/ReactInstanceHandles.js +12 -12
- package/lib/ReactIsomorphic.js +11 -11
- package/lib/ReactLink.js +1 -1
- package/lib/ReactMarkupChecksum.js +6 -2
- package/lib/ReactMount.js +88 -88
- package/lib/ReactMultiChild.js +83 -22
- package/lib/ReactMultiChildUpdateTypes.js +2 -1
- package/lib/ReactNativeComponent.js +3 -8
- package/lib/ReactNoopUpdateQueue.js +118 -0
- package/lib/ReactOwner.js +3 -3
- package/lib/ReactPerf.js +2 -2
- package/lib/ReactPropTransferer.js +3 -3
- package/lib/ReactPropTypeLocationNames.js +1 -1
- package/lib/ReactPropTypeLocations.js +1 -1
- package/lib/ReactPropTypes.js +49 -11
- package/lib/ReactReconcileTransaction.js +8 -8
- package/lib/ReactReconciler.js +18 -20
- package/lib/ReactRef.js +1 -1
- package/lib/ReactServerBatchingStrategy.js +23 -0
- package/lib/ReactServerRendering.js +22 -9
- package/lib/ReactServerRenderingTransaction.js +7 -7
- package/lib/ReactTestUtils.js +80 -58
- package/lib/ReactTransitionChildMapping.js +2 -2
- package/lib/ReactTransitionEvents.js +1 -1
- package/lib/ReactTransitionGroup.js +5 -6
- package/lib/ReactUpdateQueue.js +61 -36
- package/lib/ReactUpdates.js +14 -17
- package/lib/ReactWithAddons.js +14 -16
- package/lib/ResponderEventPlugin.js +514 -0
- package/lib/ResponderSyntheticEvent.js +40 -0
- package/lib/ResponderTouchHistoryStore.js +180 -0
- package/lib/SVGDOMPropertyConfig.js +1 -1
- package/lib/SelectEventPlugin.js +14 -15
- package/lib/SimpleEventPlugin.js +205 -29
- package/lib/SyntheticClipboardEvent.js +3 -3
- package/lib/SyntheticCompositionEvent.js +3 -3
- package/lib/SyntheticDragEvent.js +3 -3
- package/lib/SyntheticEvent.js +9 -8
- package/lib/SyntheticFocusEvent.js +3 -3
- package/lib/SyntheticInputEvent.js +3 -3
- package/lib/SyntheticKeyboardEvent.js +6 -6
- package/lib/SyntheticMouseEvent.js +5 -5
- package/lib/SyntheticTouchEvent.js +4 -4
- package/lib/SyntheticUIEvent.js +4 -4
- package/lib/SyntheticWheelEvent.js +3 -3
- package/lib/TapEventPlugin.js +119 -0
- package/lib/Transaction.js +16 -10
- package/lib/accumulate.js +44 -0
- package/lib/accumulateInto.js +2 -2
- package/lib/adler32.js +19 -7
- package/lib/cloneWithProps.js +12 -7
- package/lib/createHierarchyRenderer.js +85 -0
- package/lib/dangerousStyleValue.js +1 -1
- package/lib/deprecated.js +47 -0
- package/lib/findDOMNode.js +11 -12
- package/lib/flattenChildren.js +4 -4
- package/lib/forEachAccumulated.js +1 -1
- package/lib/getEventCharCode.js +1 -1
- package/lib/getEventKey.js +1 -1
- package/lib/getEventModifierState.js +0 -1
- package/lib/getTestDocument.js +28 -0
- package/lib/getTextContentAccessor.js +1 -1
- package/lib/instantiateReactComponent.js +24 -20
- package/lib/isEventSupported.js +1 -1
- package/lib/isTextInputElement.js +2 -1
- package/lib/joinClasses.js +1 -1
- package/lib/onlyChild.js +3 -3
- package/lib/quoteAttributeValueForBrowser.js +1 -1
- package/lib/reactComponentExpect.js +210 -0
- package/lib/renderSubtreeIntoContainer.js +1 -1
- package/lib/setInnerHTML.js +2 -2
- package/lib/setTextContent.js +3 -3
- package/lib/shallowCompare.js +1 -1
- package/lib/sliceChildren.js +51 -0
- package/lib/traverseAllChildren.js +15 -14
- package/lib/update.js +13 -13
- package/lib/validateDOMNesting.js +14 -6
- package/lib/webcomponents.js +6379 -0
- package/package.json +4 -6
- package/react.js +53 -1
- package/addons/CSSTransitionGroup.js +0 -1
- package/addons/LinkedStateMixin.js +0 -1
- package/addons/Perf.js +0 -1
- package/addons/PureRenderMixin.js +0 -1
- package/addons/TestUtils.js +0 -1
- package/addons/TransitionGroup.js +0 -1
- package/addons/batchedUpdates.js +0 -1
- package/addons/cloneWithProps.js +0 -1
- package/addons/createFragment.js +0 -1
- package/addons/renderSubtreeIntoContainer.js +0 -1
- package/addons/shallowCompare.js +0 -1
- package/addons/update.js +0 -1
- package/lib/CSSCore.js +0 -97
- package/lib/EventListener.js +0 -84
- package/lib/ExecutionEnvironment.js +0 -38
- package/lib/LocalEventTrapMixin.js +0 -46
- package/lib/ReactContext.js +0 -32
- package/lib/ReactDOMClient.js +0 -85
- 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/camelize.js +0 -32
- package/lib/camelizeStyleName.js +0 -40
- package/lib/containsNode.js +0 -55
- package/lib/createArrayFromMixed.js +0 -85
- package/lib/createFullPageComponent.js +0 -51
- package/lib/createNodesFromMarkup.js +0 -84
- package/lib/emptyFunction.js +0 -38
- package/lib/emptyObject.js +0 -20
- package/lib/focusNode.js +0 -26
- package/lib/getActiveElement.js +0 -29
- package/lib/getMarkupWrap.js +0 -115
- package/lib/getUnboundedScrollPosition.js +0 -38
- package/lib/hyphenate.js +0 -33
- package/lib/hyphenateStyleName.js +0 -39
- package/lib/invariant.js +0 -49
- package/lib/isNode.js +0 -23
- package/lib/isTextNode.js +0 -25
- package/lib/keyMirror.js +0 -48
- package/lib/keyOf.js +0 -35
- package/lib/mapObject.js +0 -51
- package/lib/performance.js +0 -23
- package/lib/performanceNow.js +0 -28
- package/lib/shallowEqual.js +0 -48
- package/lib/toArray.js +0 -57
- package/lib/warning.js +0 -61
package/lib/ReactDOM.js
CHANGED
|
@@ -7,170 +7,84 @@
|
|
|
7
7
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
8
8
|
*
|
|
9
9
|
* @providesModule ReactDOM
|
|
10
|
-
* @typechecks static-only
|
|
11
10
|
*/
|
|
12
11
|
|
|
12
|
+
/* globals __REACT_DEVTOOLS_GLOBAL_HOOK__*/
|
|
13
|
+
|
|
13
14
|
'use strict';
|
|
14
15
|
|
|
15
|
-
var
|
|
16
|
-
var
|
|
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');
|
|
17
24
|
|
|
18
|
-
var
|
|
25
|
+
var findDOMNode = require('./findDOMNode');
|
|
26
|
+
var renderSubtreeIntoContainer = require('./renderSubtreeIntoContainer');
|
|
27
|
+
var warning = require('fbjs/lib/warning');
|
|
19
28
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
+
/* eslint-enable camelcase */
|
|
46
|
+
if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject === 'function') {
|
|
47
|
+
__REACT_DEVTOOLS_GLOBAL_HOOK__.inject({
|
|
48
|
+
CurrentOwner: ReactCurrentOwner,
|
|
49
|
+
InstanceHandles: ReactInstanceHandles,
|
|
50
|
+
Mount: ReactMount,
|
|
51
|
+
Reconciler: ReactReconciler,
|
|
52
|
+
TextComponent: ReactDOMTextComponent
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
57
|
+
var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');
|
|
58
|
+
if (ExecutionEnvironment.canUseDOM && window.top === window.self) {
|
|
59
|
+
|
|
60
|
+
// If we're in Chrome, look for the devtools marker and provide a download
|
|
61
|
+
// link if not installed.
|
|
62
|
+
if (navigator.userAgent.indexOf('Chrome') > -1) {
|
|
63
|
+
if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
|
|
64
|
+
console.debug('Download the React DevTools for a better development experience: ' + 'https://fb.me/react-devtools');
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// If we're in IE8, check to see if we are in combatibility mode and provide
|
|
69
|
+
// information on preventing compatibility mode
|
|
70
|
+
var ieCompatibilityMode = document.documentMode && document.documentMode < 8;
|
|
71
|
+
|
|
72
|
+
process.env.NODE_ENV !== '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" />') : undefined;
|
|
73
|
+
|
|
74
|
+
var expectedFeatures = [
|
|
75
|
+
// shims
|
|
76
|
+
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,
|
|
77
|
+
|
|
78
|
+
// shams
|
|
79
|
+
Object.create, Object.freeze];
|
|
80
|
+
|
|
81
|
+
for (var i = 0; i < expectedFeatures.length; i++) {
|
|
82
|
+
if (!expectedFeatures[i]) {
|
|
83
|
+
console.error('One or more ES5 shim/shams expected by React are not available: ' + 'https://fb.me/react-warning-polyfills');
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
29
87
|
}
|
|
30
|
-
return ReactElement.createFactory(tag);
|
|
31
88
|
}
|
|
32
89
|
|
|
33
|
-
|
|
34
|
-
* Creates a mapping from supported HTML tags to `ReactDOMComponent` classes.
|
|
35
|
-
* This is also accessible via `React.DOM`.
|
|
36
|
-
*
|
|
37
|
-
* @public
|
|
38
|
-
*/
|
|
39
|
-
var ReactDOM = mapObject({
|
|
40
|
-
a: 'a',
|
|
41
|
-
abbr: 'abbr',
|
|
42
|
-
address: 'address',
|
|
43
|
-
area: 'area',
|
|
44
|
-
article: 'article',
|
|
45
|
-
aside: 'aside',
|
|
46
|
-
audio: 'audio',
|
|
47
|
-
b: 'b',
|
|
48
|
-
base: 'base',
|
|
49
|
-
bdi: 'bdi',
|
|
50
|
-
bdo: 'bdo',
|
|
51
|
-
big: 'big',
|
|
52
|
-
blockquote: 'blockquote',
|
|
53
|
-
body: 'body',
|
|
54
|
-
br: 'br',
|
|
55
|
-
button: 'button',
|
|
56
|
-
canvas: 'canvas',
|
|
57
|
-
caption: 'caption',
|
|
58
|
-
cite: 'cite',
|
|
59
|
-
code: 'code',
|
|
60
|
-
col: 'col',
|
|
61
|
-
colgroup: 'colgroup',
|
|
62
|
-
data: 'data',
|
|
63
|
-
datalist: 'datalist',
|
|
64
|
-
dd: 'dd',
|
|
65
|
-
del: 'del',
|
|
66
|
-
details: 'details',
|
|
67
|
-
dfn: 'dfn',
|
|
68
|
-
dialog: 'dialog',
|
|
69
|
-
div: 'div',
|
|
70
|
-
dl: 'dl',
|
|
71
|
-
dt: 'dt',
|
|
72
|
-
em: 'em',
|
|
73
|
-
embed: 'embed',
|
|
74
|
-
fieldset: 'fieldset',
|
|
75
|
-
figcaption: 'figcaption',
|
|
76
|
-
figure: 'figure',
|
|
77
|
-
footer: 'footer',
|
|
78
|
-
form: 'form',
|
|
79
|
-
h1: 'h1',
|
|
80
|
-
h2: 'h2',
|
|
81
|
-
h3: 'h3',
|
|
82
|
-
h4: 'h4',
|
|
83
|
-
h5: 'h5',
|
|
84
|
-
h6: 'h6',
|
|
85
|
-
head: 'head',
|
|
86
|
-
header: 'header',
|
|
87
|
-
hgroup: 'hgroup',
|
|
88
|
-
hr: 'hr',
|
|
89
|
-
html: 'html',
|
|
90
|
-
i: 'i',
|
|
91
|
-
iframe: 'iframe',
|
|
92
|
-
img: 'img',
|
|
93
|
-
input: 'input',
|
|
94
|
-
ins: 'ins',
|
|
95
|
-
kbd: 'kbd',
|
|
96
|
-
keygen: 'keygen',
|
|
97
|
-
label: 'label',
|
|
98
|
-
legend: 'legend',
|
|
99
|
-
li: 'li',
|
|
100
|
-
link: 'link',
|
|
101
|
-
main: 'main',
|
|
102
|
-
map: 'map',
|
|
103
|
-
mark: 'mark',
|
|
104
|
-
menu: 'menu',
|
|
105
|
-
menuitem: 'menuitem',
|
|
106
|
-
meta: 'meta',
|
|
107
|
-
meter: 'meter',
|
|
108
|
-
nav: 'nav',
|
|
109
|
-
noscript: 'noscript',
|
|
110
|
-
object: 'object',
|
|
111
|
-
ol: 'ol',
|
|
112
|
-
optgroup: 'optgroup',
|
|
113
|
-
option: 'option',
|
|
114
|
-
output: 'output',
|
|
115
|
-
p: 'p',
|
|
116
|
-
param: 'param',
|
|
117
|
-
picture: 'picture',
|
|
118
|
-
pre: 'pre',
|
|
119
|
-
progress: 'progress',
|
|
120
|
-
q: 'q',
|
|
121
|
-
rp: 'rp',
|
|
122
|
-
rt: 'rt',
|
|
123
|
-
ruby: 'ruby',
|
|
124
|
-
s: 's',
|
|
125
|
-
samp: 'samp',
|
|
126
|
-
script: 'script',
|
|
127
|
-
section: 'section',
|
|
128
|
-
select: 'select',
|
|
129
|
-
small: 'small',
|
|
130
|
-
source: 'source',
|
|
131
|
-
span: 'span',
|
|
132
|
-
strong: 'strong',
|
|
133
|
-
style: 'style',
|
|
134
|
-
sub: 'sub',
|
|
135
|
-
summary: 'summary',
|
|
136
|
-
sup: 'sup',
|
|
137
|
-
table: 'table',
|
|
138
|
-
tbody: 'tbody',
|
|
139
|
-
td: 'td',
|
|
140
|
-
textarea: 'textarea',
|
|
141
|
-
tfoot: 'tfoot',
|
|
142
|
-
th: 'th',
|
|
143
|
-
thead: 'thead',
|
|
144
|
-
time: 'time',
|
|
145
|
-
title: 'title',
|
|
146
|
-
tr: 'tr',
|
|
147
|
-
track: 'track',
|
|
148
|
-
u: 'u',
|
|
149
|
-
ul: 'ul',
|
|
150
|
-
'var': 'var',
|
|
151
|
-
video: 'video',
|
|
152
|
-
wbr: 'wbr',
|
|
153
|
-
|
|
154
|
-
// SVG
|
|
155
|
-
circle: 'circle',
|
|
156
|
-
clipPath: 'clipPath',
|
|
157
|
-
defs: 'defs',
|
|
158
|
-
ellipse: 'ellipse',
|
|
159
|
-
g: 'g',
|
|
160
|
-
line: 'line',
|
|
161
|
-
linearGradient: 'linearGradient',
|
|
162
|
-
mask: 'mask',
|
|
163
|
-
path: 'path',
|
|
164
|
-
pattern: 'pattern',
|
|
165
|
-
polygon: 'polygon',
|
|
166
|
-
polyline: 'polyline',
|
|
167
|
-
radialGradient: 'radialGradient',
|
|
168
|
-
rect: 'rect',
|
|
169
|
-
stop: 'stop',
|
|
170
|
-
svg: 'svg',
|
|
171
|
-
text: 'text',
|
|
172
|
-
tspan: 'tspan'
|
|
173
|
-
|
|
174
|
-
}, createDOMFactory);
|
|
175
|
-
|
|
176
|
-
module.exports = ReactDOM;
|
|
90
|
+
module.exports = React;
|
package/lib/ReactDOMButton.js
CHANGED
|
@@ -11,51 +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
|
-
|
|
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];
|
|
53
43
|
}
|
|
54
44
|
}
|
|
55
45
|
|
|
56
|
-
return
|
|
46
|
+
return nativeProps;
|
|
57
47
|
}
|
|
58
|
-
|
|
59
|
-
});
|
|
48
|
+
};
|
|
60
49
|
|
|
61
50
|
module.exports = ReactDOMButton;
|
package/lib/ReactDOMComponent.js
CHANGED
|
@@ -14,23 +14,31 @@
|
|
|
14
14
|
|
|
15
15
|
'use strict';
|
|
16
16
|
|
|
17
|
-
var
|
|
18
|
-
var
|
|
19
|
-
var
|
|
20
|
-
var
|
|
21
|
-
var
|
|
22
|
-
var
|
|
23
|
-
var
|
|
24
|
-
var
|
|
25
|
-
|
|
26
|
-
var
|
|
27
|
-
var
|
|
28
|
-
var
|
|
29
|
-
var
|
|
30
|
-
var
|
|
31
|
-
var
|
|
32
|
-
var
|
|
33
|
-
|
|
17
|
+
var AutoFocusUtils = require('./AutoFocusUtils');
|
|
18
|
+
var CSSPropertyOperations = require('./CSSPropertyOperations');
|
|
19
|
+
var DOMProperty = require('./DOMProperty');
|
|
20
|
+
var DOMPropertyOperations = require('./DOMPropertyOperations');
|
|
21
|
+
var EventConstants = require('./EventConstants');
|
|
22
|
+
var ReactBrowserEventEmitter = require('./ReactBrowserEventEmitter');
|
|
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');
|
|
29
|
+
var ReactMount = require('./ReactMount');
|
|
30
|
+
var ReactMultiChild = require('./ReactMultiChild');
|
|
31
|
+
var ReactPerf = require('./ReactPerf');
|
|
32
|
+
var ReactUpdateQueue = require('./ReactUpdateQueue');
|
|
33
|
+
|
|
34
|
+
var assign = require('./Object.assign');
|
|
35
|
+
var escapeTextContentForBrowser = require('./escapeTextContentForBrowser');
|
|
36
|
+
var invariant = require('fbjs/lib/invariant');
|
|
37
|
+
var isEventSupported = require('./isEventSupported');
|
|
38
|
+
var keyOf = require('fbjs/lib/keyOf');
|
|
39
|
+
var shallowEqual = require('fbjs/lib/shallowEqual');
|
|
40
|
+
var validateDOMNesting = require('./validateDOMNesting');
|
|
41
|
+
var warning = require('fbjs/lib/warning');
|
|
34
42
|
|
|
35
43
|
var deleteListener = ReactBrowserEventEmitter.deleteListener;
|
|
36
44
|
var listenTo = ReactBrowserEventEmitter.listenTo;
|
|
@@ -43,6 +51,90 @@ var STYLE = keyOf({ style: null });
|
|
|
43
51
|
|
|
44
52
|
var ELEMENT_NODE_TYPE = 1;
|
|
45
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 (process.env.NODE_ENV !== 'production') {
|
|
75
|
+
legacyPropsDescriptor = {
|
|
76
|
+
props: {
|
|
77
|
+
enumerable: false,
|
|
78
|
+
get: function () {
|
|
79
|
+
var component = this._reactInternalComponent;
|
|
80
|
+
process.env.NODE_ENV !== 'production' ? warning(false, 'ReactDOMComponent: Do not access .props of a DOM node; instead, ' + 'recreate the props as `render` did originally or read the DOM ' + 'properties/attributes directly from this node (e.g., ' + 'this.refs.box.className).%s', getDeclarationErrorAddendum(component)) : undefined;
|
|
81
|
+
return component._currentElement.props;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function legacyGetDOMNode() {
|
|
88
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
89
|
+
var component = this._reactInternalComponent;
|
|
90
|
+
process.env.NODE_ENV !== 'production' ? 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 (process.env.NODE_ENV !== 'production') {
|
|
98
|
+
process.env.NODE_ENV !== 'production' ? 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 (process.env.NODE_ENV !== 'production') {
|
|
105
|
+
var component = this._reactInternalComponent;
|
|
106
|
+
process.env.NODE_ENV !== 'production' ? 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 (process.env.NODE_ENV !== 'production') {
|
|
113
|
+
process.env.NODE_ENV !== 'production' ? 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 (process.env.NODE_ENV !== 'production') {
|
|
127
|
+
process.env.NODE_ENV !== 'production' ? 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
|
+
|
|
46
138
|
var styleMutationWarning = {};
|
|
47
139
|
|
|
48
140
|
function checkAndWarnForMutatedStyle(style1, style2, component) {
|
|
@@ -68,7 +160,7 @@ function checkAndWarnForMutatedStyle(style1, style2, component) {
|
|
|
68
160
|
|
|
69
161
|
styleMutationWarning[hash] = true;
|
|
70
162
|
|
|
71
|
-
|
|
163
|
+
process.env.NODE_ENV !== '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 + '>', JSON.stringify(style1), JSON.stringify(style2)) : undefined;
|
|
72
164
|
}
|
|
73
165
|
|
|
74
166
|
/**
|
|
@@ -77,6 +169,7 @@ function checkAndWarnForMutatedStyle(style1, style2, component) {
|
|
|
77
169
|
var BackendIDOperations = null;
|
|
78
170
|
|
|
79
171
|
/**
|
|
172
|
+
* @param {object} component
|
|
80
173
|
* @param {?object} props
|
|
81
174
|
*/
|
|
82
175
|
function assertValidProps(component, props) {
|
|
@@ -84,27 +177,27 @@ function assertValidProps(component, props) {
|
|
|
84
177
|
return;
|
|
85
178
|
}
|
|
86
179
|
// Note the use of `==` which checks for null or undefined.
|
|
87
|
-
if (
|
|
180
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
88
181
|
if (voidElementTags[component._tag]) {
|
|
89
|
-
|
|
182
|
+
process.env.NODE_ENV !== 'production' ? warning(props.children == null && props.dangerouslySetInnerHTML == null, '%s is a void element tag and must not have `children` or ' + 'use `props.dangerouslySetInnerHTML`.%s', component._tag, component._currentElement._owner ? ' Check the render method of ' + component._currentElement._owner.getName() + '.' : '') : undefined;
|
|
90
183
|
}
|
|
91
184
|
}
|
|
92
185
|
if (props.dangerouslySetInnerHTML != null) {
|
|
93
|
-
|
|
94
|
-
|
|
186
|
+
!(props.children == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : invariant(false) : undefined;
|
|
187
|
+
!(typeof props.dangerouslySetInnerHTML === 'object' && '__html' in props.dangerouslySetInnerHTML) ? process.env.NODE_ENV !== 'production' ? invariant(false, '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' + 'Please visit https://fb.me/react-invariant-dangerously-set-inner-html ' + 'for more information.') : invariant(false) : undefined;
|
|
95
188
|
}
|
|
96
|
-
if (
|
|
97
|
-
|
|
98
|
-
|
|
189
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
190
|
+
process.env.NODE_ENV !== 'production' ? warning(props.innerHTML == null, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.') : undefined;
|
|
191
|
+
process.env.NODE_ENV !== 'production' ? warning(!props.contentEditable || props.children == null, 'A component is `contentEditable` and contains `children` managed by ' + 'React. It is now your responsibility to guarantee that none of ' + 'those nodes are unexpectedly modified or duplicated. This is ' + 'probably not intentional.') : undefined;
|
|
99
192
|
}
|
|
100
|
-
|
|
193
|
+
!(props.style == null || typeof props.style === 'object') ? process.env.NODE_ENV !== '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.') : invariant(false) : undefined;
|
|
101
194
|
}
|
|
102
195
|
|
|
103
196
|
function enqueuePutListener(id, registrationName, listener, transaction) {
|
|
104
|
-
if (
|
|
197
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
105
198
|
// IE8 has no API for event capturing and the `onScroll` event doesn't
|
|
106
199
|
// bubble.
|
|
107
|
-
|
|
200
|
+
process.env.NODE_ENV !== 'production' ? warning(registrationName !== 'onScroll' || isEventSupported('scroll', true), 'This browser doesn\'t support the `onScroll` event') : undefined;
|
|
108
201
|
}
|
|
109
202
|
var container = ReactMount.findReactContainerForID(id);
|
|
110
203
|
if (container) {
|
|
@@ -123,6 +216,71 @@ function putListener() {
|
|
|
123
216
|
ReactBrowserEventEmitter.putListener(listenerToPut.id, listenerToPut.registrationName, listenerToPut.listener);
|
|
124
217
|
}
|
|
125
218
|
|
|
219
|
+
// There are so many media events, it makes sense to just
|
|
220
|
+
// maintain a list rather than create a `trapBubbledEvent` for each
|
|
221
|
+
var mediaEvents = {
|
|
222
|
+
topAbort: 'abort',
|
|
223
|
+
topCanPlay: 'canplay',
|
|
224
|
+
topCanPlayThrough: 'canplaythrough',
|
|
225
|
+
topDurationChange: 'durationchange',
|
|
226
|
+
topEmptied: 'emptied',
|
|
227
|
+
topEncrypted: 'encrypted',
|
|
228
|
+
topEnded: 'ended',
|
|
229
|
+
topError: 'error',
|
|
230
|
+
topLoadedData: 'loadeddata',
|
|
231
|
+
topLoadedMetadata: 'loadedmetadata',
|
|
232
|
+
topLoadStart: 'loadstart',
|
|
233
|
+
topPause: 'pause',
|
|
234
|
+
topPlay: 'play',
|
|
235
|
+
topPlaying: 'playing',
|
|
236
|
+
topProgress: 'progress',
|
|
237
|
+
topRateChange: 'ratechange',
|
|
238
|
+
topSeeked: 'seeked',
|
|
239
|
+
topSeeking: 'seeking',
|
|
240
|
+
topStalled: 'stalled',
|
|
241
|
+
topSuspend: 'suspend',
|
|
242
|
+
topTimeUpdate: 'timeupdate',
|
|
243
|
+
topVolumeChange: 'volumechange',
|
|
244
|
+
topWaiting: 'waiting'
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
function trapBubbledEventsLocal() {
|
|
248
|
+
var inst = this;
|
|
249
|
+
// If a component renders to null or if another component fatals and causes
|
|
250
|
+
// the state of the tree to be corrupted, `node` here can be null.
|
|
251
|
+
!inst._rootNodeID ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Must be mounted to trap events') : invariant(false) : undefined;
|
|
252
|
+
var node = ReactMount.getNode(inst._rootNodeID);
|
|
253
|
+
!node ? process.env.NODE_ENV !== 'production' ? invariant(false, 'trapBubbledEvent(...): Requires node to be rendered.') : invariant(false) : undefined;
|
|
254
|
+
|
|
255
|
+
switch (inst._tag) {
|
|
256
|
+
case 'iframe':
|
|
257
|
+
inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topLoad, 'load', node)];
|
|
258
|
+
break;
|
|
259
|
+
case 'video':
|
|
260
|
+
case 'audio':
|
|
261
|
+
|
|
262
|
+
inst._wrapperState.listeners = [];
|
|
263
|
+
// create listener for each media event
|
|
264
|
+
for (var event in mediaEvents) {
|
|
265
|
+
if (mediaEvents.hasOwnProperty(event)) {
|
|
266
|
+
inst._wrapperState.listeners.push(ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes[event], mediaEvents[event], node));
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
break;
|
|
271
|
+
case 'img':
|
|
272
|
+
inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topError, 'error', node), ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topLoad, 'load', node)];
|
|
273
|
+
break;
|
|
274
|
+
case 'form':
|
|
275
|
+
inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topReset, 'reset', node), ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topSubmit, 'submit', node)];
|
|
276
|
+
break;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function postUpdateSelectWrapper() {
|
|
281
|
+
ReactDOMSelect.postUpdateWrapper(this);
|
|
282
|
+
}
|
|
283
|
+
|
|
126
284
|
// For HTML, certain tags should omit their close tag. We keep a whitelist for
|
|
127
285
|
// those special cased tags.
|
|
128
286
|
|
|
@@ -142,9 +300,9 @@ var omittedCloseTags = {
|
|
|
142
300
|
'source': true,
|
|
143
301
|
'track': true,
|
|
144
302
|
'wbr': true
|
|
145
|
-
// NOTE: menuitem's close tag should be omitted, but that causes problems.
|
|
146
303
|
};
|
|
147
304
|
|
|
305
|
+
// NOTE: menuitem's close tag should be omitted, but that causes problems.
|
|
148
306
|
var newlineEatingTags = {
|
|
149
307
|
'listing': true,
|
|
150
308
|
'pre': true,
|
|
@@ -168,13 +326,13 @@ var hasOwnProperty = ({}).hasOwnProperty;
|
|
|
168
326
|
|
|
169
327
|
function validateDangerousTag(tag) {
|
|
170
328
|
if (!hasOwnProperty.call(validatedTagCache, tag)) {
|
|
171
|
-
|
|
329
|
+
!VALID_TAG_REGEX.test(tag) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Invalid tag: %s', tag) : invariant(false) : undefined;
|
|
172
330
|
validatedTagCache[tag] = true;
|
|
173
331
|
}
|
|
174
332
|
}
|
|
175
333
|
|
|
176
334
|
function processChildContext(context, inst) {
|
|
177
|
-
if (
|
|
335
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
178
336
|
// Pass down our tag name to child components for validation purposes
|
|
179
337
|
context = assign({}, context);
|
|
180
338
|
var info = context[validateDOMNesting.ancestorInfoContextKey];
|
|
@@ -183,6 +341,10 @@ function processChildContext(context, inst) {
|
|
|
183
341
|
return context;
|
|
184
342
|
}
|
|
185
343
|
|
|
344
|
+
function isCustomComponent(tagName, props) {
|
|
345
|
+
return tagName.indexOf('-') >= 0 || props.is != null;
|
|
346
|
+
}
|
|
347
|
+
|
|
186
348
|
/**
|
|
187
349
|
* Creates a new React class that is idempotent and capable of containing other
|
|
188
350
|
* React components. It accepts event listeners and DOM properties that are
|
|
@@ -199,11 +361,14 @@ function processChildContext(context, inst) {
|
|
|
199
361
|
*/
|
|
200
362
|
function ReactDOMComponent(tag) {
|
|
201
363
|
validateDangerousTag(tag);
|
|
202
|
-
this._tag = tag;
|
|
364
|
+
this._tag = tag.toLowerCase();
|
|
203
365
|
this._renderedChildren = null;
|
|
204
366
|
this._previousStyle = null;
|
|
205
367
|
this._previousStyleCopy = null;
|
|
206
368
|
this._rootNodeID = null;
|
|
369
|
+
this._wrapperState = null;
|
|
370
|
+
this._topLevelWrapper = null;
|
|
371
|
+
this._nodeWithLegacyProperties = null;
|
|
207
372
|
}
|
|
208
373
|
|
|
209
374
|
ReactDOMComponent.displayName = 'ReactDOMComponent';
|
|
@@ -227,19 +392,66 @@ ReactDOMComponent.Mixin = {
|
|
|
227
392
|
mountComponent: function (rootID, transaction, context) {
|
|
228
393
|
this._rootNodeID = rootID;
|
|
229
394
|
|
|
230
|
-
|
|
231
|
-
|
|
395
|
+
var props = this._currentElement.props;
|
|
396
|
+
|
|
397
|
+
switch (this._tag) {
|
|
398
|
+
case 'iframe':
|
|
399
|
+
case 'img':
|
|
400
|
+
case 'form':
|
|
401
|
+
case 'video':
|
|
402
|
+
case 'audio':
|
|
403
|
+
this._wrapperState = {
|
|
404
|
+
listeners: null
|
|
405
|
+
};
|
|
406
|
+
transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this);
|
|
407
|
+
break;
|
|
408
|
+
case 'button':
|
|
409
|
+
props = ReactDOMButton.getNativeProps(this, props, context);
|
|
410
|
+
break;
|
|
411
|
+
case 'input':
|
|
412
|
+
ReactDOMInput.mountWrapper(this, props, context);
|
|
413
|
+
props = ReactDOMInput.getNativeProps(this, props, context);
|
|
414
|
+
break;
|
|
415
|
+
case 'option':
|
|
416
|
+
ReactDOMOption.mountWrapper(this, props, context);
|
|
417
|
+
props = ReactDOMOption.getNativeProps(this, props, context);
|
|
418
|
+
break;
|
|
419
|
+
case 'select':
|
|
420
|
+
ReactDOMSelect.mountWrapper(this, props, context);
|
|
421
|
+
props = ReactDOMSelect.getNativeProps(this, props, context);
|
|
422
|
+
context = ReactDOMSelect.processChildContext(this, props, context);
|
|
423
|
+
break;
|
|
424
|
+
case 'textarea':
|
|
425
|
+
ReactDOMTextarea.mountWrapper(this, props, context);
|
|
426
|
+
props = ReactDOMTextarea.getNativeProps(this, props, context);
|
|
427
|
+
break;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
assertValidProps(this, props);
|
|
431
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
232
432
|
if (context[validateDOMNesting.ancestorInfoContextKey]) {
|
|
233
433
|
validateDOMNesting(this._tag, this, context[validateDOMNesting.ancestorInfoContextKey]);
|
|
234
434
|
}
|
|
235
435
|
}
|
|
236
436
|
|
|
237
|
-
var tagOpen = this._createOpenTagMarkupAndPutListeners(transaction);
|
|
238
|
-
var tagContent = this._createContentMarkup(transaction, context);
|
|
437
|
+
var tagOpen = this._createOpenTagMarkupAndPutListeners(transaction, props);
|
|
438
|
+
var tagContent = this._createContentMarkup(transaction, props, context);
|
|
439
|
+
|
|
440
|
+
switch (this._tag) {
|
|
441
|
+
case 'button':
|
|
442
|
+
case 'input':
|
|
443
|
+
case 'select':
|
|
444
|
+
case 'textarea':
|
|
445
|
+
if (props.autoFocus) {
|
|
446
|
+
transaction.getReactMountReady().enqueue(AutoFocusUtils.focusDOMComponent, this);
|
|
447
|
+
}
|
|
448
|
+
break;
|
|
449
|
+
}
|
|
450
|
+
|
|
239
451
|
if (!tagContent && omittedCloseTags[this._tag]) {
|
|
240
452
|
return tagOpen + '/>';
|
|
241
453
|
}
|
|
242
|
-
return tagOpen + '>' + tagContent + '</' + this.
|
|
454
|
+
return tagOpen + '>' + tagContent + '</' + this._currentElement.type + '>';
|
|
243
455
|
},
|
|
244
456
|
|
|
245
457
|
/**
|
|
@@ -252,11 +464,11 @@ ReactDOMComponent.Mixin = {
|
|
|
252
464
|
*
|
|
253
465
|
* @private
|
|
254
466
|
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
|
|
467
|
+
* @param {object} props
|
|
255
468
|
* @return {string} Markup of opening tag.
|
|
256
469
|
*/
|
|
257
|
-
_createOpenTagMarkupAndPutListeners: function (transaction) {
|
|
258
|
-
var
|
|
259
|
-
var ret = '<' + this._tag;
|
|
470
|
+
_createOpenTagMarkupAndPutListeners: function (transaction, props) {
|
|
471
|
+
var ret = '<' + this._currentElement.type;
|
|
260
472
|
|
|
261
473
|
for (var propKey in props) {
|
|
262
474
|
if (!props.hasOwnProperty(propKey)) {
|
|
@@ -271,7 +483,7 @@ ReactDOMComponent.Mixin = {
|
|
|
271
483
|
} else {
|
|
272
484
|
if (propKey === STYLE) {
|
|
273
485
|
if (propValue) {
|
|
274
|
-
if (
|
|
486
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
275
487
|
// See `_updateDOMProperties`. style block
|
|
276
488
|
this._previousStyle = propValue;
|
|
277
489
|
}
|
|
@@ -279,7 +491,12 @@ ReactDOMComponent.Mixin = {
|
|
|
279
491
|
}
|
|
280
492
|
propValue = CSSPropertyOperations.createMarkupForStyles(propValue);
|
|
281
493
|
}
|
|
282
|
-
var markup =
|
|
494
|
+
var markup = null;
|
|
495
|
+
if (this._tag != null && isCustomComponent(this._tag, props)) {
|
|
496
|
+
markup = DOMPropertyOperations.createMarkupForCustomAttribute(propKey, propValue);
|
|
497
|
+
} else {
|
|
498
|
+
markup = DOMPropertyOperations.createMarkupForProperty(propKey, propValue);
|
|
499
|
+
}
|
|
283
500
|
if (markup) {
|
|
284
501
|
ret += ' ' + markup;
|
|
285
502
|
}
|
|
@@ -301,12 +518,12 @@ ReactDOMComponent.Mixin = {
|
|
|
301
518
|
*
|
|
302
519
|
* @private
|
|
303
520
|
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
|
|
521
|
+
* @param {object} props
|
|
304
522
|
* @param {object} context
|
|
305
523
|
* @return {string} Content markup.
|
|
306
524
|
*/
|
|
307
|
-
_createContentMarkup: function (transaction, context) {
|
|
525
|
+
_createContentMarkup: function (transaction, props, context) {
|
|
308
526
|
var ret = '';
|
|
309
|
-
var props = this._currentElement.props;
|
|
310
527
|
|
|
311
528
|
// Intentional use of != to avoid catching zero/false.
|
|
312
529
|
var innerHTML = props.dangerouslySetInnerHTML;
|
|
@@ -367,9 +584,47 @@ ReactDOMComponent.Mixin = {
|
|
|
367
584
|
* @overridable
|
|
368
585
|
*/
|
|
369
586
|
updateComponent: function (transaction, prevElement, nextElement, context) {
|
|
370
|
-
|
|
371
|
-
this.
|
|
372
|
-
|
|
587
|
+
var lastProps = prevElement.props;
|
|
588
|
+
var nextProps = this._currentElement.props;
|
|
589
|
+
|
|
590
|
+
switch (this._tag) {
|
|
591
|
+
case 'button':
|
|
592
|
+
lastProps = ReactDOMButton.getNativeProps(this, lastProps);
|
|
593
|
+
nextProps = ReactDOMButton.getNativeProps(this, nextProps);
|
|
594
|
+
break;
|
|
595
|
+
case 'input':
|
|
596
|
+
ReactDOMInput.updateWrapper(this);
|
|
597
|
+
lastProps = ReactDOMInput.getNativeProps(this, lastProps);
|
|
598
|
+
nextProps = ReactDOMInput.getNativeProps(this, nextProps);
|
|
599
|
+
break;
|
|
600
|
+
case 'option':
|
|
601
|
+
lastProps = ReactDOMOption.getNativeProps(this, lastProps);
|
|
602
|
+
nextProps = ReactDOMOption.getNativeProps(this, nextProps);
|
|
603
|
+
break;
|
|
604
|
+
case 'select':
|
|
605
|
+
lastProps = ReactDOMSelect.getNativeProps(this, lastProps);
|
|
606
|
+
nextProps = ReactDOMSelect.getNativeProps(this, nextProps);
|
|
607
|
+
break;
|
|
608
|
+
case 'textarea':
|
|
609
|
+
ReactDOMTextarea.updateWrapper(this);
|
|
610
|
+
lastProps = ReactDOMTextarea.getNativeProps(this, lastProps);
|
|
611
|
+
nextProps = ReactDOMTextarea.getNativeProps(this, nextProps);
|
|
612
|
+
break;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
assertValidProps(this, nextProps);
|
|
616
|
+
this._updateDOMProperties(lastProps, nextProps, transaction);
|
|
617
|
+
this._updateDOMChildren(lastProps, nextProps, transaction, processChildContext(context, this));
|
|
618
|
+
|
|
619
|
+
if (!canDefineProperty && this._nodeWithLegacyProperties) {
|
|
620
|
+
this._nodeWithLegacyProperties.props = nextProps;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
if (this._tag === 'select') {
|
|
624
|
+
// <select> value update needs to occur after <option> children
|
|
625
|
+
// reconciliation
|
|
626
|
+
transaction.getReactMountReady().enqueue(postUpdateSelectWrapper, this);
|
|
627
|
+
}
|
|
373
628
|
},
|
|
374
629
|
|
|
375
630
|
/**
|
|
@@ -385,10 +640,10 @@ ReactDOMComponent.Mixin = {
|
|
|
385
640
|
*
|
|
386
641
|
* @private
|
|
387
642
|
* @param {object} lastProps
|
|
643
|
+
* @param {object} nextProps
|
|
388
644
|
* @param {ReactReconcileTransaction} transaction
|
|
389
645
|
*/
|
|
390
|
-
_updateDOMProperties: function (lastProps, transaction) {
|
|
391
|
-
var nextProps = this._currentElement.props;
|
|
646
|
+
_updateDOMProperties: function (lastProps, nextProps, transaction) {
|
|
392
647
|
var propKey;
|
|
393
648
|
var styleName;
|
|
394
649
|
var styleUpdates;
|
|
@@ -412,7 +667,7 @@ ReactDOMComponent.Mixin = {
|
|
|
412
667
|
// listener (e.g., onClick={null})
|
|
413
668
|
deleteListener(this._rootNodeID, propKey);
|
|
414
669
|
}
|
|
415
|
-
} else if (DOMProperty.
|
|
670
|
+
} else if (DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) {
|
|
416
671
|
BackendIDOperations.deletePropertyByID(this._rootNodeID, propKey);
|
|
417
672
|
}
|
|
418
673
|
}
|
|
@@ -424,7 +679,7 @@ ReactDOMComponent.Mixin = {
|
|
|
424
679
|
}
|
|
425
680
|
if (propKey === STYLE) {
|
|
426
681
|
if (nextProp) {
|
|
427
|
-
if (
|
|
682
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
428
683
|
checkAndWarnForMutatedStyle(this._previousStyleCopy, this._previousStyle, this);
|
|
429
684
|
this._previousStyle = nextProp;
|
|
430
685
|
}
|
|
@@ -457,7 +712,9 @@ ReactDOMComponent.Mixin = {
|
|
|
457
712
|
} else if (lastProp) {
|
|
458
713
|
deleteListener(this._rootNodeID, propKey);
|
|
459
714
|
}
|
|
460
|
-
} else if (
|
|
715
|
+
} else if (isCustomComponent(this._tag, nextProps)) {
|
|
716
|
+
BackendIDOperations.updateAttributeByID(this._rootNodeID, propKey, nextProp);
|
|
717
|
+
} else if (DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) {
|
|
461
718
|
BackendIDOperations.updatePropertyByID(this._rootNodeID, propKey, nextProp);
|
|
462
719
|
}
|
|
463
720
|
}
|
|
@@ -471,11 +728,11 @@ ReactDOMComponent.Mixin = {
|
|
|
471
728
|
* children content.
|
|
472
729
|
*
|
|
473
730
|
* @param {object} lastProps
|
|
731
|
+
* @param {object} nextProps
|
|
474
732
|
* @param {ReactReconcileTransaction} transaction
|
|
733
|
+
* @param {object} context
|
|
475
734
|
*/
|
|
476
|
-
_updateDOMChildren: function (lastProps, transaction, context) {
|
|
477
|
-
var nextProps = this._currentElement.props;
|
|
478
|
-
|
|
735
|
+
_updateDOMChildren: function (lastProps, nextProps, transaction, context) {
|
|
479
736
|
var lastContent = CONTENT_TYPES[typeof lastProps.children] ? lastProps.children : null;
|
|
480
737
|
var nextContent = CONTENT_TYPES[typeof nextProps.children] ? nextProps.children : null;
|
|
481
738
|
|
|
@@ -502,7 +759,7 @@ ReactDOMComponent.Mixin = {
|
|
|
502
759
|
}
|
|
503
760
|
} else if (nextHtml != null) {
|
|
504
761
|
if (lastHtml !== nextHtml) {
|
|
505
|
-
|
|
762
|
+
this.updateMarkup('' + nextHtml);
|
|
506
763
|
}
|
|
507
764
|
} else if (nextChildren != null) {
|
|
508
765
|
this.updateChildren(nextChildren, transaction, context);
|
|
@@ -516,10 +773,75 @@ ReactDOMComponent.Mixin = {
|
|
|
516
773
|
* @internal
|
|
517
774
|
*/
|
|
518
775
|
unmountComponent: function () {
|
|
776
|
+
switch (this._tag) {
|
|
777
|
+
case 'iframe':
|
|
778
|
+
case 'img':
|
|
779
|
+
case 'form':
|
|
780
|
+
case 'video':
|
|
781
|
+
case 'audio':
|
|
782
|
+
var listeners = this._wrapperState.listeners;
|
|
783
|
+
if (listeners) {
|
|
784
|
+
for (var i = 0; i < listeners.length; i++) {
|
|
785
|
+
listeners[i].remove();
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
break;
|
|
789
|
+
case 'input':
|
|
790
|
+
ReactDOMInput.unmountWrapper(this);
|
|
791
|
+
break;
|
|
792
|
+
case 'html':
|
|
793
|
+
case 'head':
|
|
794
|
+
case 'body':
|
|
795
|
+
/**
|
|
796
|
+
* Components like <html> <head> and <body> can't be removed or added
|
|
797
|
+
* easily in a cross-browser way, however it's valuable to be able to
|
|
798
|
+
* take advantage of React's reconciliation for styling and <title>
|
|
799
|
+
* management. So we just document it and throw in dangerous cases.
|
|
800
|
+
*/
|
|
801
|
+
!false ? process.env.NODE_ENV !== '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) : invariant(false) : undefined;
|
|
802
|
+
break;
|
|
803
|
+
}
|
|
804
|
+
|
|
519
805
|
this.unmountChildren();
|
|
520
806
|
ReactBrowserEventEmitter.deleteAllListeners(this._rootNodeID);
|
|
521
807
|
ReactComponentBrowserEnvironment.unmountIDFromEnvironment(this._rootNodeID);
|
|
522
808
|
this._rootNodeID = null;
|
|
809
|
+
this._wrapperState = null;
|
|
810
|
+
if (this._nodeWithLegacyProperties) {
|
|
811
|
+
var node = this._nodeWithLegacyProperties;
|
|
812
|
+
node._reactInternalComponent = null;
|
|
813
|
+
this._nodeWithLegacyProperties = null;
|
|
814
|
+
}
|
|
815
|
+
},
|
|
816
|
+
|
|
817
|
+
getPublicInstance: function () {
|
|
818
|
+
if (!this._nodeWithLegacyProperties) {
|
|
819
|
+
var node = ReactMount.getNode(this._rootNodeID);
|
|
820
|
+
|
|
821
|
+
node._reactInternalComponent = this;
|
|
822
|
+
node.getDOMNode = legacyGetDOMNode;
|
|
823
|
+
node.isMounted = legacyIsMounted;
|
|
824
|
+
node.setState = legacySetStateEtc;
|
|
825
|
+
node.replaceState = legacySetStateEtc;
|
|
826
|
+
node.forceUpdate = legacySetStateEtc;
|
|
827
|
+
node.setProps = legacySetProps;
|
|
828
|
+
node.replaceProps = legacyReplaceProps;
|
|
829
|
+
|
|
830
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
831
|
+
if (canDefineProperty) {
|
|
832
|
+
Object.defineProperties(node, legacyPropsDescriptor);
|
|
833
|
+
} else {
|
|
834
|
+
// updateComponent will update this property on subsequent renders
|
|
835
|
+
node.props = this._currentElement.props;
|
|
836
|
+
}
|
|
837
|
+
} else {
|
|
838
|
+
// updateComponent will update this property on subsequent renders
|
|
839
|
+
node.props = this._currentElement.props;
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
this._nodeWithLegacyProperties = node;
|
|
843
|
+
}
|
|
844
|
+
return this._nodeWithLegacyProperties;
|
|
523
845
|
}
|
|
524
846
|
|
|
525
847
|
};
|