react 0.14.0-alpha3 → 0.14.0-rc1
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 +8 -3
- package/dist/react-dom.js +42 -0
- package/dist/react-dom.min.js +12 -0
- package/dist/react-with-addons.js +6076 -5337
- package/dist/react-with-addons.min.js +6 -6
- package/dist/react.js +5445 -4839
- 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 +18 -3
- package/lib/CSSPropertyOperations.js +22 -14
- package/lib/CallbackQueue.js +4 -4
- package/lib/ChangeEventPlugin.js +18 -15
- package/lib/DOMChildrenOperations.js +17 -7
- package/lib/DOMProperty.js +82 -117
- package/lib/DOMPropertyOperations.js +84 -33
- package/lib/Danger.js +21 -16
- package/lib/DefaultEventPluginOrder.js +2 -2
- package/lib/EnterLeaveEventPlugin.js +21 -13
- package/lib/EventConstants.js +23 -1
- package/lib/EventPluginHub.js +17 -20
- package/lib/EventPluginRegistry.js +8 -8
- package/lib/EventPluginUtils.js +33 -42
- package/lib/EventPropagators.js +8 -8
- package/lib/FallbackCompositionState.js +9 -3
- package/lib/HTMLDOMPropertyConfig.js +19 -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 +15 -5
- package/lib/React.js +18 -7
- package/lib/ReactBrowserComponentMixin.js +4 -4
- package/lib/ReactBrowserEventEmitter.js +30 -7
- package/lib/ReactCSSTransitionGroup.js +35 -9
- package/lib/ReactCSSTransitionGroupChild.js +56 -30
- package/lib/ReactChildReconciler.js +24 -19
- package/lib/ReactChildren.js +75 -35
- package/lib/ReactClass.js +70 -87
- package/lib/ReactComponent.js +27 -20
- package/lib/ReactComponentBrowserEnvironment.js +2 -2
- package/lib/ReactComponentEnvironment.js +2 -2
- package/lib/ReactComponentWithPureRenderMixin.js +3 -3
- package/lib/ReactCompositeComponent.js +117 -106
- package/lib/ReactDOM.js +74 -158
- package/lib/ReactDOMButton.js +15 -26
- package/lib/ReactDOMComponent.js +441 -72
- package/lib/ReactDOMFactories.js +177 -0
- package/lib/{emptyObject.js → ReactDOMFeatureFlags.js} +6 -8
- package/lib/ReactDOMIDOperations.js +8 -66
- package/lib/ReactDOMInput.js +87 -99
- package/lib/ReactDOMOption.js +25 -44
- package/lib/ReactDOMSelect.js +88 -98
- package/lib/ReactDOMSelection.js +3 -3
- package/lib/ReactDOMServer.js +5 -3
- package/lib/ReactDOMTextComponent.js +33 -20
- package/lib/ReactDOMTextarea.js +48 -61
- package/lib/ReactDefaultBatchingStrategy.js +4 -4
- package/lib/ReactDefaultInjection.js +23 -72
- package/lib/ReactDefaultPerf.js +7 -7
- package/lib/ReactDefaultPerfAnalysis.js +6 -11
- package/lib/ReactElement.js +92 -107
- package/lib/ReactElementValidator.js +53 -173
- package/lib/ReactEmptyComponent.js +26 -62
- package/lib/ReactEmptyComponentRegistry.js +48 -0
- package/lib/ReactErrorUtils.js +45 -9
- package/lib/ReactEventEmitterMixin.js +3 -4
- package/lib/ReactEventListener.js +64 -12
- package/lib/ReactFragment.js +29 -115
- package/lib/ReactInjection.js +10 -12
- package/lib/ReactInputSelection.js +8 -7
- package/lib/ReactInstanceHandles.js +12 -12
- package/lib/ReactIsomorphic.js +15 -11
- package/lib/ReactLink.js +1 -1
- package/lib/ReactMarkupChecksum.js +6 -2
- package/lib/ReactMount.js +196 -122
- package/lib/ReactMultiChild.js +119 -25
- 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 +41 -12
- package/lib/ReactReconcileTransaction.js +12 -10
- package/lib/ReactReconciler.js +8 -11
- package/lib/ReactRef.js +15 -2
- package/lib/ReactServerBatchingStrategy.js +23 -0
- package/lib/ReactServerRendering.js +22 -9
- package/lib/ReactServerRenderingTransaction.js +8 -7
- package/lib/ReactTestUtils.js +89 -64
- package/lib/ReactTransitionChildMapping.js +3 -6
- package/lib/ReactTransitionEvents.js +1 -1
- package/lib/ReactTransitionGroup.js +5 -6
- package/lib/ReactUpdateQueue.js +60 -35
- package/lib/ReactUpdates.js +15 -18
- package/lib/{isTextNode.js → ReactVersion.js} +2 -13
- package/lib/ReactWithAddons.js +24 -17
- 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 +25 -16
- package/lib/SimpleEventPlugin.js +200 -45
- package/lib/SyntheticClipboardEvent.js +3 -3
- package/lib/SyntheticCompositionEvent.js +3 -3
- package/lib/SyntheticDragEvent.js +3 -3
- package/lib/SyntheticEvent.js +24 -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 +17 -11
- 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 +48 -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 +27 -25
- 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 +216 -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/shouldUpdateReactComponent.js +12 -8
- package/lib/sliceChildren.js +34 -0
- package/lib/traverseAllChildren.js +21 -19
- package/lib/update.js +13 -13
- package/lib/validateDOMNesting.js +6 -6
- package/lib/webcomponents.js +6379 -0
- package/package.json +4 -6
- package/react.js +2 -0
- 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/dist/JSXTransformer.js +0 -17589
- 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/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/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,86 @@
|
|
|
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');
|
|
24
|
+
var ReactVersion = require('./ReactVersion');
|
|
17
25
|
|
|
18
|
-
var
|
|
26
|
+
var findDOMNode = require('./findDOMNode');
|
|
27
|
+
var renderSubtreeIntoContainer = require('./renderSubtreeIntoContainer');
|
|
28
|
+
var warning = require('fbjs/lib/warning');
|
|
19
29
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
30
|
+
ReactDefaultInjection.inject();
|
|
31
|
+
|
|
32
|
+
var render = ReactPerf.measure('React', 'render', ReactMount.render);
|
|
33
|
+
|
|
34
|
+
var React = {
|
|
35
|
+
findDOMNode: findDOMNode,
|
|
36
|
+
render: render,
|
|
37
|
+
unmountComponentAtNode: ReactMount.unmountComponentAtNode,
|
|
38
|
+
version: ReactVersion,
|
|
39
|
+
|
|
40
|
+
/* eslint-disable camelcase */
|
|
41
|
+
unstable_batchedUpdates: ReactUpdates.batchedUpdates,
|
|
42
|
+
unstable_renderSubtreeIntoContainer: renderSubtreeIntoContainer
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// Inject the runtime into a devtools global hook regardless of browser.
|
|
46
|
+
// Allows for debugging when the hook is injected on the page.
|
|
47
|
+
/* eslint-enable camelcase */
|
|
48
|
+
if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject === 'function') {
|
|
49
|
+
__REACT_DEVTOOLS_GLOBAL_HOOK__.inject({
|
|
50
|
+
CurrentOwner: ReactCurrentOwner,
|
|
51
|
+
InstanceHandles: ReactInstanceHandles,
|
|
52
|
+
Mount: ReactMount,
|
|
53
|
+
Reconciler: ReactReconciler,
|
|
54
|
+
TextComponent: ReactDOMTextComponent
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
59
|
+
var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');
|
|
60
|
+
if (ExecutionEnvironment.canUseDOM && window.top === window.self) {
|
|
61
|
+
|
|
62
|
+
// First check if devtools is not installed
|
|
63
|
+
if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
|
|
64
|
+
// If we're in Chrome or Firefox, provide a download link if not installed.
|
|
65
|
+
if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
|
|
66
|
+
console.debug('Download the React DevTools for a better development experience: ' + 'https://fb.me/react-devtools');
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// If we're in IE8, check to see if we are in compatibility mode and provide
|
|
71
|
+
// information on preventing compatibility mode
|
|
72
|
+
var ieCompatibilityMode = document.documentMode && document.documentMode < 8;
|
|
73
|
+
|
|
74
|
+
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;
|
|
75
|
+
|
|
76
|
+
var expectedFeatures = [
|
|
77
|
+
// shims
|
|
78
|
+
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,
|
|
79
|
+
|
|
80
|
+
// shams
|
|
81
|
+
Object.create, Object.freeze];
|
|
82
|
+
|
|
83
|
+
for (var i = 0; i < expectedFeatures.length; i++) {
|
|
84
|
+
if (!expectedFeatures[i]) {
|
|
85
|
+
console.error('One or more ES5 shim/shams expected by React are not available: ' + 'https://fb.me/react-warning-polyfills');
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
29
89
|
}
|
|
30
|
-
return ReactElement.createFactory(tag);
|
|
31
90
|
}
|
|
32
91
|
|
|
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;
|
|
92
|
+
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,33 @@
|
|
|
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 setInnerHTML = require('./setInnerHTML');
|
|
40
|
+
var setTextContent = require('./setTextContent');
|
|
41
|
+
var shallowEqual = require('fbjs/lib/shallowEqual');
|
|
42
|
+
var validateDOMNesting = require('./validateDOMNesting');
|
|
43
|
+
var warning = require('fbjs/lib/warning');
|
|
34
44
|
|
|
35
45
|
var deleteListener = ReactBrowserEventEmitter.deleteListener;
|
|
36
46
|
var listenTo = ReactBrowserEventEmitter.listenTo;
|
|
@@ -43,6 +53,90 @@ var STYLE = keyOf({ style: null });
|
|
|
43
53
|
|
|
44
54
|
var ELEMENT_NODE_TYPE = 1;
|
|
45
55
|
|
|
56
|
+
var canDefineProperty = false;
|
|
57
|
+
try {
|
|
58
|
+
Object.defineProperty({}, 'test', { get: function () {} });
|
|
59
|
+
canDefineProperty = true;
|
|
60
|
+
} catch (e) {}
|
|
61
|
+
|
|
62
|
+
function getDeclarationErrorAddendum(internalInstance) {
|
|
63
|
+
if (internalInstance) {
|
|
64
|
+
var owner = internalInstance._currentElement._owner || null;
|
|
65
|
+
if (owner) {
|
|
66
|
+
var name = owner.getName();
|
|
67
|
+
if (name) {
|
|
68
|
+
return ' This DOM node was rendered by `' + name + '`.';
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return '';
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
var legacyPropsDescriptor;
|
|
76
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
77
|
+
legacyPropsDescriptor = {
|
|
78
|
+
props: {
|
|
79
|
+
enumerable: false,
|
|
80
|
+
get: function () {
|
|
81
|
+
var component = this._reactInternalComponent;
|
|
82
|
+
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;
|
|
83
|
+
return component._currentElement.props;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function legacyGetDOMNode() {
|
|
90
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
91
|
+
var component = this._reactInternalComponent;
|
|
92
|
+
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;
|
|
93
|
+
}
|
|
94
|
+
return this;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function legacyIsMounted() {
|
|
98
|
+
var component = this._reactInternalComponent;
|
|
99
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
100
|
+
process.env.NODE_ENV !== 'production' ? warning(false, 'ReactDOMComponent: Do not access .isMounted() of a DOM node.%s', getDeclarationErrorAddendum(component)) : undefined;
|
|
101
|
+
}
|
|
102
|
+
return !!component;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function legacySetStateEtc() {
|
|
106
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
107
|
+
var component = this._reactInternalComponent;
|
|
108
|
+
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;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function legacySetProps(partialProps, callback) {
|
|
113
|
+
var component = this._reactInternalComponent;
|
|
114
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
115
|
+
process.env.NODE_ENV !== 'production' ? warning(false, 'ReactDOMComponent: Do not access .setProps() of a DOM node. ' + 'Instead, call ReactDOM.render again at the top level.%s', getDeclarationErrorAddendum(component)) : undefined;
|
|
116
|
+
}
|
|
117
|
+
if (!component) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
ReactUpdateQueue.enqueueSetPropsInternal(component, partialProps);
|
|
121
|
+
if (callback) {
|
|
122
|
+
ReactUpdateQueue.enqueueCallbackInternal(component, callback);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function legacyReplaceProps(partialProps, callback) {
|
|
127
|
+
var component = this._reactInternalComponent;
|
|
128
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
129
|
+
process.env.NODE_ENV !== 'production' ? warning(false, 'ReactDOMComponent: Do not access .replaceProps() of a DOM node. ' + 'Instead, call ReactDOM.render again at the top level.%s', getDeclarationErrorAddendum(component)) : undefined;
|
|
130
|
+
}
|
|
131
|
+
if (!component) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
ReactUpdateQueue.enqueueReplacePropsInternal(component, partialProps);
|
|
135
|
+
if (callback) {
|
|
136
|
+
ReactUpdateQueue.enqueueCallbackInternal(component, callback);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
46
140
|
var styleMutationWarning = {};
|
|
47
141
|
|
|
48
142
|
function checkAndWarnForMutatedStyle(style1, style2, component) {
|
|
@@ -68,15 +162,11 @@ function checkAndWarnForMutatedStyle(style1, style2, component) {
|
|
|
68
162
|
|
|
69
163
|
styleMutationWarning[hash] = true;
|
|
70
164
|
|
|
71
|
-
|
|
165
|
+
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
166
|
}
|
|
73
167
|
|
|
74
168
|
/**
|
|
75
|
-
*
|
|
76
|
-
*/
|
|
77
|
-
var BackendIDOperations = null;
|
|
78
|
-
|
|
79
|
-
/**
|
|
169
|
+
* @param {object} component
|
|
80
170
|
* @param {?object} props
|
|
81
171
|
*/
|
|
82
172
|
function assertValidProps(component, props) {
|
|
@@ -84,27 +174,27 @@ function assertValidProps(component, props) {
|
|
|
84
174
|
return;
|
|
85
175
|
}
|
|
86
176
|
// Note the use of `==` which checks for null or undefined.
|
|
87
|
-
if (
|
|
177
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
88
178
|
if (voidElementTags[component._tag]) {
|
|
89
|
-
|
|
179
|
+
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
180
|
}
|
|
91
181
|
}
|
|
92
182
|
if (props.dangerouslySetInnerHTML != null) {
|
|
93
|
-
!(props.children == null) ?
|
|
94
|
-
!(typeof props.dangerouslySetInnerHTML === 'object' && '__html' in props.dangerouslySetInnerHTML) ?
|
|
183
|
+
!(props.children == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : invariant(false) : undefined;
|
|
184
|
+
!(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
185
|
}
|
|
96
|
-
if (
|
|
97
|
-
|
|
98
|
-
|
|
186
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
187
|
+
process.env.NODE_ENV !== 'production' ? warning(props.innerHTML == null, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.') : undefined;
|
|
188
|
+
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
189
|
}
|
|
100
|
-
!(props.style == null || typeof props.style === 'object') ?
|
|
190
|
+
!(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.%s', getDeclarationErrorAddendum(component)) : invariant(false) : undefined;
|
|
101
191
|
}
|
|
102
192
|
|
|
103
193
|
function enqueuePutListener(id, registrationName, listener, transaction) {
|
|
104
|
-
if (
|
|
194
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
105
195
|
// IE8 has no API for event capturing and the `onScroll` event doesn't
|
|
106
196
|
// bubble.
|
|
107
|
-
|
|
197
|
+
process.env.NODE_ENV !== 'production' ? warning(registrationName !== 'onScroll' || isEventSupported('scroll', true), 'This browser doesn\'t support the `onScroll` event') : undefined;
|
|
108
198
|
}
|
|
109
199
|
var container = ReactMount.findReactContainerForID(id);
|
|
110
200
|
if (container) {
|
|
@@ -123,6 +213,71 @@ function putListener() {
|
|
|
123
213
|
ReactBrowserEventEmitter.putListener(listenerToPut.id, listenerToPut.registrationName, listenerToPut.listener);
|
|
124
214
|
}
|
|
125
215
|
|
|
216
|
+
// There are so many media events, it makes sense to just
|
|
217
|
+
// maintain a list rather than create a `trapBubbledEvent` for each
|
|
218
|
+
var mediaEvents = {
|
|
219
|
+
topAbort: 'abort',
|
|
220
|
+
topCanPlay: 'canplay',
|
|
221
|
+
topCanPlayThrough: 'canplaythrough',
|
|
222
|
+
topDurationChange: 'durationchange',
|
|
223
|
+
topEmptied: 'emptied',
|
|
224
|
+
topEncrypted: 'encrypted',
|
|
225
|
+
topEnded: 'ended',
|
|
226
|
+
topError: 'error',
|
|
227
|
+
topLoadedData: 'loadeddata',
|
|
228
|
+
topLoadedMetadata: 'loadedmetadata',
|
|
229
|
+
topLoadStart: 'loadstart',
|
|
230
|
+
topPause: 'pause',
|
|
231
|
+
topPlay: 'play',
|
|
232
|
+
topPlaying: 'playing',
|
|
233
|
+
topProgress: 'progress',
|
|
234
|
+
topRateChange: 'ratechange',
|
|
235
|
+
topSeeked: 'seeked',
|
|
236
|
+
topSeeking: 'seeking',
|
|
237
|
+
topStalled: 'stalled',
|
|
238
|
+
topSuspend: 'suspend',
|
|
239
|
+
topTimeUpdate: 'timeupdate',
|
|
240
|
+
topVolumeChange: 'volumechange',
|
|
241
|
+
topWaiting: 'waiting'
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
function trapBubbledEventsLocal() {
|
|
245
|
+
var inst = this;
|
|
246
|
+
// If a component renders to null or if another component fatals and causes
|
|
247
|
+
// the state of the tree to be corrupted, `node` here can be null.
|
|
248
|
+
!inst._rootNodeID ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Must be mounted to trap events') : invariant(false) : undefined;
|
|
249
|
+
var node = ReactMount.getNode(inst._rootNodeID);
|
|
250
|
+
!node ? process.env.NODE_ENV !== 'production' ? invariant(false, 'trapBubbledEvent(...): Requires node to be rendered.') : invariant(false) : undefined;
|
|
251
|
+
|
|
252
|
+
switch (inst._tag) {
|
|
253
|
+
case 'iframe':
|
|
254
|
+
inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topLoad, 'load', node)];
|
|
255
|
+
break;
|
|
256
|
+
case 'video':
|
|
257
|
+
case 'audio':
|
|
258
|
+
|
|
259
|
+
inst._wrapperState.listeners = [];
|
|
260
|
+
// create listener for each media event
|
|
261
|
+
for (var event in mediaEvents) {
|
|
262
|
+
if (mediaEvents.hasOwnProperty(event)) {
|
|
263
|
+
inst._wrapperState.listeners.push(ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes[event], mediaEvents[event], node));
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
break;
|
|
268
|
+
case 'img':
|
|
269
|
+
inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topError, 'error', node), ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topLoad, 'load', node)];
|
|
270
|
+
break;
|
|
271
|
+
case 'form':
|
|
272
|
+
inst._wrapperState.listeners = [ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topReset, 'reset', node), ReactBrowserEventEmitter.trapBubbledEvent(EventConstants.topLevelTypes.topSubmit, 'submit', node)];
|
|
273
|
+
break;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function postUpdateSelectWrapper() {
|
|
278
|
+
ReactDOMSelect.postUpdateWrapper(this);
|
|
279
|
+
}
|
|
280
|
+
|
|
126
281
|
// For HTML, certain tags should omit their close tag. We keep a whitelist for
|
|
127
282
|
// those special cased tags.
|
|
128
283
|
|
|
@@ -142,9 +297,9 @@ var omittedCloseTags = {
|
|
|
142
297
|
'source': true,
|
|
143
298
|
'track': true,
|
|
144
299
|
'wbr': true
|
|
145
|
-
// NOTE: menuitem's close tag should be omitted, but that causes problems.
|
|
146
300
|
};
|
|
147
301
|
|
|
302
|
+
// NOTE: menuitem's close tag should be omitted, but that causes problems.
|
|
148
303
|
var newlineEatingTags = {
|
|
149
304
|
'listing': true,
|
|
150
305
|
'pre': true,
|
|
@@ -168,13 +323,13 @@ var hasOwnProperty = ({}).hasOwnProperty;
|
|
|
168
323
|
|
|
169
324
|
function validateDangerousTag(tag) {
|
|
170
325
|
if (!hasOwnProperty.call(validatedTagCache, tag)) {
|
|
171
|
-
!VALID_TAG_REGEX.test(tag) ?
|
|
326
|
+
!VALID_TAG_REGEX.test(tag) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Invalid tag: %s', tag) : invariant(false) : undefined;
|
|
172
327
|
validatedTagCache[tag] = true;
|
|
173
328
|
}
|
|
174
329
|
}
|
|
175
330
|
|
|
176
331
|
function processChildContext(context, inst) {
|
|
177
|
-
if (
|
|
332
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
178
333
|
// Pass down our tag name to child components for validation purposes
|
|
179
334
|
context = assign({}, context);
|
|
180
335
|
var info = context[validateDOMNesting.ancestorInfoContextKey];
|
|
@@ -183,6 +338,10 @@ function processChildContext(context, inst) {
|
|
|
183
338
|
return context;
|
|
184
339
|
}
|
|
185
340
|
|
|
341
|
+
function isCustomComponent(tagName, props) {
|
|
342
|
+
return tagName.indexOf('-') >= 0 || props.is != null;
|
|
343
|
+
}
|
|
344
|
+
|
|
186
345
|
/**
|
|
187
346
|
* Creates a new React class that is idempotent and capable of containing other
|
|
188
347
|
* React components. It accepts event listeners and DOM properties that are
|
|
@@ -199,11 +358,14 @@ function processChildContext(context, inst) {
|
|
|
199
358
|
*/
|
|
200
359
|
function ReactDOMComponent(tag) {
|
|
201
360
|
validateDangerousTag(tag);
|
|
202
|
-
this._tag = tag;
|
|
361
|
+
this._tag = tag.toLowerCase();
|
|
203
362
|
this._renderedChildren = null;
|
|
204
363
|
this._previousStyle = null;
|
|
205
364
|
this._previousStyleCopy = null;
|
|
206
365
|
this._rootNodeID = null;
|
|
366
|
+
this._wrapperState = null;
|
|
367
|
+
this._topLevelWrapper = null;
|
|
368
|
+
this._nodeWithLegacyProperties = null;
|
|
207
369
|
}
|
|
208
370
|
|
|
209
371
|
ReactDOMComponent.displayName = 'ReactDOMComponent';
|
|
@@ -227,19 +389,80 @@ ReactDOMComponent.Mixin = {
|
|
|
227
389
|
mountComponent: function (rootID, transaction, context) {
|
|
228
390
|
this._rootNodeID = rootID;
|
|
229
391
|
|
|
230
|
-
|
|
231
|
-
|
|
392
|
+
var props = this._currentElement.props;
|
|
393
|
+
|
|
394
|
+
switch (this._tag) {
|
|
395
|
+
case 'iframe':
|
|
396
|
+
case 'img':
|
|
397
|
+
case 'form':
|
|
398
|
+
case 'video':
|
|
399
|
+
case 'audio':
|
|
400
|
+
this._wrapperState = {
|
|
401
|
+
listeners: null
|
|
402
|
+
};
|
|
403
|
+
transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this);
|
|
404
|
+
break;
|
|
405
|
+
case 'button':
|
|
406
|
+
props = ReactDOMButton.getNativeProps(this, props, context);
|
|
407
|
+
break;
|
|
408
|
+
case 'input':
|
|
409
|
+
ReactDOMInput.mountWrapper(this, props, context);
|
|
410
|
+
props = ReactDOMInput.getNativeProps(this, props, context);
|
|
411
|
+
break;
|
|
412
|
+
case 'option':
|
|
413
|
+
ReactDOMOption.mountWrapper(this, props, context);
|
|
414
|
+
props = ReactDOMOption.getNativeProps(this, props, context);
|
|
415
|
+
break;
|
|
416
|
+
case 'select':
|
|
417
|
+
ReactDOMSelect.mountWrapper(this, props, context);
|
|
418
|
+
props = ReactDOMSelect.getNativeProps(this, props, context);
|
|
419
|
+
context = ReactDOMSelect.processChildContext(this, props, context);
|
|
420
|
+
break;
|
|
421
|
+
case 'textarea':
|
|
422
|
+
ReactDOMTextarea.mountWrapper(this, props, context);
|
|
423
|
+
props = ReactDOMTextarea.getNativeProps(this, props, context);
|
|
424
|
+
break;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
assertValidProps(this, props);
|
|
428
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
232
429
|
if (context[validateDOMNesting.ancestorInfoContextKey]) {
|
|
233
430
|
validateDOMNesting(this._tag, this, context[validateDOMNesting.ancestorInfoContextKey]);
|
|
234
431
|
}
|
|
235
432
|
}
|
|
236
433
|
|
|
237
|
-
var
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
434
|
+
var mountImage;
|
|
435
|
+
if (transaction.useCreateElement) {
|
|
436
|
+
var ownerDocument = context[ReactMount.ownerDocumentContextKey];
|
|
437
|
+
var el = ownerDocument.createElement(this._currentElement.type);
|
|
438
|
+
DOMPropertyOperations.setAttributeForID(el, this._rootNodeID);
|
|
439
|
+
// Populate node cache
|
|
440
|
+
ReactMount.getID(el);
|
|
441
|
+
this._updateDOMProperties({}, props, transaction, el);
|
|
442
|
+
this._createInitialChildren(transaction, props, context, el);
|
|
443
|
+
mountImage = el;
|
|
444
|
+
} else {
|
|
445
|
+
var tagOpen = this._createOpenTagMarkupAndPutListeners(transaction, props);
|
|
446
|
+
var tagContent = this._createContentMarkup(transaction, props, context);
|
|
447
|
+
if (!tagContent && omittedCloseTags[this._tag]) {
|
|
448
|
+
mountImage = tagOpen + '/>';
|
|
449
|
+
} else {
|
|
450
|
+
mountImage = tagOpen + '>' + tagContent + '</' + this._currentElement.type + '>';
|
|
451
|
+
}
|
|
241
452
|
}
|
|
242
|
-
|
|
453
|
+
|
|
454
|
+
switch (this._tag) {
|
|
455
|
+
case 'button':
|
|
456
|
+
case 'input':
|
|
457
|
+
case 'select':
|
|
458
|
+
case 'textarea':
|
|
459
|
+
if (props.autoFocus) {
|
|
460
|
+
transaction.getReactMountReady().enqueue(AutoFocusUtils.focusDOMComponent, this);
|
|
461
|
+
}
|
|
462
|
+
break;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
return mountImage;
|
|
243
466
|
},
|
|
244
467
|
|
|
245
468
|
/**
|
|
@@ -252,11 +475,11 @@ ReactDOMComponent.Mixin = {
|
|
|
252
475
|
*
|
|
253
476
|
* @private
|
|
254
477
|
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
|
|
478
|
+
* @param {object} props
|
|
255
479
|
* @return {string} Markup of opening tag.
|
|
256
480
|
*/
|
|
257
|
-
_createOpenTagMarkupAndPutListeners: function (transaction) {
|
|
258
|
-
var
|
|
259
|
-
var ret = '<' + this._tag;
|
|
481
|
+
_createOpenTagMarkupAndPutListeners: function (transaction, props) {
|
|
482
|
+
var ret = '<' + this._currentElement.type;
|
|
260
483
|
|
|
261
484
|
for (var propKey in props) {
|
|
262
485
|
if (!props.hasOwnProperty(propKey)) {
|
|
@@ -271,7 +494,7 @@ ReactDOMComponent.Mixin = {
|
|
|
271
494
|
} else {
|
|
272
495
|
if (propKey === STYLE) {
|
|
273
496
|
if (propValue) {
|
|
274
|
-
if (
|
|
497
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
275
498
|
// See `_updateDOMProperties`. style block
|
|
276
499
|
this._previousStyle = propValue;
|
|
277
500
|
}
|
|
@@ -279,7 +502,12 @@ ReactDOMComponent.Mixin = {
|
|
|
279
502
|
}
|
|
280
503
|
propValue = CSSPropertyOperations.createMarkupForStyles(propValue);
|
|
281
504
|
}
|
|
282
|
-
var markup =
|
|
505
|
+
var markup = null;
|
|
506
|
+
if (this._tag != null && isCustomComponent(this._tag, props)) {
|
|
507
|
+
markup = DOMPropertyOperations.createMarkupForCustomAttribute(propKey, propValue);
|
|
508
|
+
} else {
|
|
509
|
+
markup = DOMPropertyOperations.createMarkupForProperty(propKey, propValue);
|
|
510
|
+
}
|
|
283
511
|
if (markup) {
|
|
284
512
|
ret += ' ' + markup;
|
|
285
513
|
}
|
|
@@ -301,12 +529,12 @@ ReactDOMComponent.Mixin = {
|
|
|
301
529
|
*
|
|
302
530
|
* @private
|
|
303
531
|
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
|
|
532
|
+
* @param {object} props
|
|
304
533
|
* @param {object} context
|
|
305
534
|
* @return {string} Content markup.
|
|
306
535
|
*/
|
|
307
|
-
_createContentMarkup: function (transaction, context) {
|
|
536
|
+
_createContentMarkup: function (transaction, props, context) {
|
|
308
537
|
var ret = '';
|
|
309
|
-
var props = this._currentElement.props;
|
|
310
538
|
|
|
311
539
|
// Intentional use of != to avoid catching zero/false.
|
|
312
540
|
var innerHTML = props.dangerouslySetInnerHTML;
|
|
@@ -342,6 +570,28 @@ ReactDOMComponent.Mixin = {
|
|
|
342
570
|
}
|
|
343
571
|
},
|
|
344
572
|
|
|
573
|
+
_createInitialChildren: function (transaction, props, context, el) {
|
|
574
|
+
// Intentional use of != to avoid catching zero/false.
|
|
575
|
+
var innerHTML = props.dangerouslySetInnerHTML;
|
|
576
|
+
if (innerHTML != null) {
|
|
577
|
+
if (innerHTML.__html != null) {
|
|
578
|
+
setInnerHTML(el, innerHTML.__html);
|
|
579
|
+
}
|
|
580
|
+
} else {
|
|
581
|
+
var contentToUse = CONTENT_TYPES[typeof props.children] ? props.children : null;
|
|
582
|
+
var childrenToUse = contentToUse != null ? null : props.children;
|
|
583
|
+
if (contentToUse != null) {
|
|
584
|
+
// TODO: Validate that text is allowed as a child of this node
|
|
585
|
+
setTextContent(el, contentToUse);
|
|
586
|
+
} else if (childrenToUse != null) {
|
|
587
|
+
var mountImages = this.mountChildren(childrenToUse, transaction, processChildContext(context, this));
|
|
588
|
+
for (var i = 0; i < mountImages.length; i++) {
|
|
589
|
+
el.appendChild(mountImages[i]);
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
},
|
|
594
|
+
|
|
345
595
|
/**
|
|
346
596
|
* Receives a next element and updates the component.
|
|
347
597
|
*
|
|
@@ -367,9 +617,47 @@ ReactDOMComponent.Mixin = {
|
|
|
367
617
|
* @overridable
|
|
368
618
|
*/
|
|
369
619
|
updateComponent: function (transaction, prevElement, nextElement, context) {
|
|
370
|
-
|
|
371
|
-
this.
|
|
372
|
-
|
|
620
|
+
var lastProps = prevElement.props;
|
|
621
|
+
var nextProps = this._currentElement.props;
|
|
622
|
+
|
|
623
|
+
switch (this._tag) {
|
|
624
|
+
case 'button':
|
|
625
|
+
lastProps = ReactDOMButton.getNativeProps(this, lastProps);
|
|
626
|
+
nextProps = ReactDOMButton.getNativeProps(this, nextProps);
|
|
627
|
+
break;
|
|
628
|
+
case 'input':
|
|
629
|
+
ReactDOMInput.updateWrapper(this);
|
|
630
|
+
lastProps = ReactDOMInput.getNativeProps(this, lastProps);
|
|
631
|
+
nextProps = ReactDOMInput.getNativeProps(this, nextProps);
|
|
632
|
+
break;
|
|
633
|
+
case 'option':
|
|
634
|
+
lastProps = ReactDOMOption.getNativeProps(this, lastProps);
|
|
635
|
+
nextProps = ReactDOMOption.getNativeProps(this, nextProps);
|
|
636
|
+
break;
|
|
637
|
+
case 'select':
|
|
638
|
+
lastProps = ReactDOMSelect.getNativeProps(this, lastProps);
|
|
639
|
+
nextProps = ReactDOMSelect.getNativeProps(this, nextProps);
|
|
640
|
+
break;
|
|
641
|
+
case 'textarea':
|
|
642
|
+
ReactDOMTextarea.updateWrapper(this);
|
|
643
|
+
lastProps = ReactDOMTextarea.getNativeProps(this, lastProps);
|
|
644
|
+
nextProps = ReactDOMTextarea.getNativeProps(this, nextProps);
|
|
645
|
+
break;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
assertValidProps(this, nextProps);
|
|
649
|
+
this._updateDOMProperties(lastProps, nextProps, transaction, null);
|
|
650
|
+
this._updateDOMChildren(lastProps, nextProps, transaction, processChildContext(context, this));
|
|
651
|
+
|
|
652
|
+
if (!canDefineProperty && this._nodeWithLegacyProperties) {
|
|
653
|
+
this._nodeWithLegacyProperties.props = nextProps;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
if (this._tag === 'select') {
|
|
657
|
+
// <select> value update needs to occur after <option> children
|
|
658
|
+
// reconciliation
|
|
659
|
+
transaction.getReactMountReady().enqueue(postUpdateSelectWrapper, this);
|
|
660
|
+
}
|
|
373
661
|
},
|
|
374
662
|
|
|
375
663
|
/**
|
|
@@ -385,10 +673,11 @@ ReactDOMComponent.Mixin = {
|
|
|
385
673
|
*
|
|
386
674
|
* @private
|
|
387
675
|
* @param {object} lastProps
|
|
676
|
+
* @param {object} nextProps
|
|
388
677
|
* @param {ReactReconcileTransaction} transaction
|
|
678
|
+
* @param {?DOMElement} node
|
|
389
679
|
*/
|
|
390
|
-
_updateDOMProperties: function (lastProps, transaction) {
|
|
391
|
-
var nextProps = this._currentElement.props;
|
|
680
|
+
_updateDOMProperties: function (lastProps, nextProps, transaction, node) {
|
|
392
681
|
var propKey;
|
|
393
682
|
var styleName;
|
|
394
683
|
var styleUpdates;
|
|
@@ -412,8 +701,11 @@ ReactDOMComponent.Mixin = {
|
|
|
412
701
|
// listener (e.g., onClick={null})
|
|
413
702
|
deleteListener(this._rootNodeID, propKey);
|
|
414
703
|
}
|
|
415
|
-
} else if (DOMProperty.
|
|
416
|
-
|
|
704
|
+
} else if (DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) {
|
|
705
|
+
if (!node) {
|
|
706
|
+
node = ReactMount.getNode(this._rootNodeID);
|
|
707
|
+
}
|
|
708
|
+
DOMPropertyOperations.deleteValueForProperty(node, propKey);
|
|
417
709
|
}
|
|
418
710
|
}
|
|
419
711
|
for (propKey in nextProps) {
|
|
@@ -424,7 +716,7 @@ ReactDOMComponent.Mixin = {
|
|
|
424
716
|
}
|
|
425
717
|
if (propKey === STYLE) {
|
|
426
718
|
if (nextProp) {
|
|
427
|
-
if (
|
|
719
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
428
720
|
checkAndWarnForMutatedStyle(this._previousStyleCopy, this._previousStyle, this);
|
|
429
721
|
this._previousStyle = nextProp;
|
|
430
722
|
}
|
|
@@ -457,12 +749,30 @@ ReactDOMComponent.Mixin = {
|
|
|
457
749
|
} else if (lastProp) {
|
|
458
750
|
deleteListener(this._rootNodeID, propKey);
|
|
459
751
|
}
|
|
460
|
-
} else if (
|
|
461
|
-
|
|
752
|
+
} else if (isCustomComponent(this._tag, nextProps)) {
|
|
753
|
+
if (!node) {
|
|
754
|
+
node = ReactMount.getNode(this._rootNodeID);
|
|
755
|
+
}
|
|
756
|
+
DOMPropertyOperations.setValueForAttribute(node, propKey, nextProp);
|
|
757
|
+
} else if (DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) {
|
|
758
|
+
if (!node) {
|
|
759
|
+
node = ReactMount.getNode(this._rootNodeID);
|
|
760
|
+
}
|
|
761
|
+
// If we're updating to null or undefined, we should remove the property
|
|
762
|
+
// from the DOM node instead of inadvertantly setting to a string. This
|
|
763
|
+
// brings us in line with the same behavior we have on initial render.
|
|
764
|
+
if (nextProp != null) {
|
|
765
|
+
DOMPropertyOperations.setValueForProperty(node, propKey, nextProp);
|
|
766
|
+
} else {
|
|
767
|
+
DOMPropertyOperations.deleteValueForProperty(node, propKey);
|
|
768
|
+
}
|
|
462
769
|
}
|
|
463
770
|
}
|
|
464
771
|
if (styleUpdates) {
|
|
465
|
-
|
|
772
|
+
if (!node) {
|
|
773
|
+
node = ReactMount.getNode(this._rootNodeID);
|
|
774
|
+
}
|
|
775
|
+
CSSPropertyOperations.setValueForStyles(node, styleUpdates);
|
|
466
776
|
}
|
|
467
777
|
},
|
|
468
778
|
|
|
@@ -471,11 +781,11 @@ ReactDOMComponent.Mixin = {
|
|
|
471
781
|
* children content.
|
|
472
782
|
*
|
|
473
783
|
* @param {object} lastProps
|
|
784
|
+
* @param {object} nextProps
|
|
474
785
|
* @param {ReactReconcileTransaction} transaction
|
|
786
|
+
* @param {object} context
|
|
475
787
|
*/
|
|
476
|
-
_updateDOMChildren: function (lastProps, transaction, context) {
|
|
477
|
-
var nextProps = this._currentElement.props;
|
|
478
|
-
|
|
788
|
+
_updateDOMChildren: function (lastProps, nextProps, transaction, context) {
|
|
479
789
|
var lastContent = CONTENT_TYPES[typeof lastProps.children] ? lastProps.children : null;
|
|
480
790
|
var nextContent = CONTENT_TYPES[typeof nextProps.children] ? nextProps.children : null;
|
|
481
791
|
|
|
@@ -502,7 +812,7 @@ ReactDOMComponent.Mixin = {
|
|
|
502
812
|
}
|
|
503
813
|
} else if (nextHtml != null) {
|
|
504
814
|
if (lastHtml !== nextHtml) {
|
|
505
|
-
|
|
815
|
+
this.updateMarkup('' + nextHtml);
|
|
506
816
|
}
|
|
507
817
|
} else if (nextChildren != null) {
|
|
508
818
|
this.updateChildren(nextChildren, transaction, context);
|
|
@@ -516,10 +826,75 @@ ReactDOMComponent.Mixin = {
|
|
|
516
826
|
* @internal
|
|
517
827
|
*/
|
|
518
828
|
unmountComponent: function () {
|
|
829
|
+
switch (this._tag) {
|
|
830
|
+
case 'iframe':
|
|
831
|
+
case 'img':
|
|
832
|
+
case 'form':
|
|
833
|
+
case 'video':
|
|
834
|
+
case 'audio':
|
|
835
|
+
var listeners = this._wrapperState.listeners;
|
|
836
|
+
if (listeners) {
|
|
837
|
+
for (var i = 0; i < listeners.length; i++) {
|
|
838
|
+
listeners[i].remove();
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
break;
|
|
842
|
+
case 'input':
|
|
843
|
+
ReactDOMInput.unmountWrapper(this);
|
|
844
|
+
break;
|
|
845
|
+
case 'html':
|
|
846
|
+
case 'head':
|
|
847
|
+
case 'body':
|
|
848
|
+
/**
|
|
849
|
+
* Components like <html> <head> and <body> can't be removed or added
|
|
850
|
+
* easily in a cross-browser way, however it's valuable to be able to
|
|
851
|
+
* take advantage of React's reconciliation for styling and <title>
|
|
852
|
+
* management. So we just document it and throw in dangerous cases.
|
|
853
|
+
*/
|
|
854
|
+
!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;
|
|
855
|
+
break;
|
|
856
|
+
}
|
|
857
|
+
|
|
519
858
|
this.unmountChildren();
|
|
520
859
|
ReactBrowserEventEmitter.deleteAllListeners(this._rootNodeID);
|
|
521
860
|
ReactComponentBrowserEnvironment.unmountIDFromEnvironment(this._rootNodeID);
|
|
522
861
|
this._rootNodeID = null;
|
|
862
|
+
this._wrapperState = null;
|
|
863
|
+
if (this._nodeWithLegacyProperties) {
|
|
864
|
+
var node = this._nodeWithLegacyProperties;
|
|
865
|
+
node._reactInternalComponent = null;
|
|
866
|
+
this._nodeWithLegacyProperties = null;
|
|
867
|
+
}
|
|
868
|
+
},
|
|
869
|
+
|
|
870
|
+
getPublicInstance: function () {
|
|
871
|
+
if (!this._nodeWithLegacyProperties) {
|
|
872
|
+
var node = ReactMount.getNode(this._rootNodeID);
|
|
873
|
+
|
|
874
|
+
node._reactInternalComponent = this;
|
|
875
|
+
node.getDOMNode = legacyGetDOMNode;
|
|
876
|
+
node.isMounted = legacyIsMounted;
|
|
877
|
+
node.setState = legacySetStateEtc;
|
|
878
|
+
node.replaceState = legacySetStateEtc;
|
|
879
|
+
node.forceUpdate = legacySetStateEtc;
|
|
880
|
+
node.setProps = legacySetProps;
|
|
881
|
+
node.replaceProps = legacyReplaceProps;
|
|
882
|
+
|
|
883
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
884
|
+
if (canDefineProperty) {
|
|
885
|
+
Object.defineProperties(node, legacyPropsDescriptor);
|
|
886
|
+
} else {
|
|
887
|
+
// updateComponent will update this property on subsequent renders
|
|
888
|
+
node.props = this._currentElement.props;
|
|
889
|
+
}
|
|
890
|
+
} else {
|
|
891
|
+
// updateComponent will update this property on subsequent renders
|
|
892
|
+
node.props = this._currentElement.props;
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
this._nodeWithLegacyProperties = node;
|
|
896
|
+
}
|
|
897
|
+
return this._nodeWithLegacyProperties;
|
|
523
898
|
}
|
|
524
899
|
|
|
525
900
|
};
|
|
@@ -531,10 +906,4 @@ ReactPerf.measureMethods(ReactDOMComponent, 'ReactDOMComponent', {
|
|
|
531
906
|
|
|
532
907
|
assign(ReactDOMComponent.prototype, ReactDOMComponent.Mixin, ReactMultiChild.Mixin);
|
|
533
908
|
|
|
534
|
-
ReactDOMComponent.injection = {
|
|
535
|
-
injectIDOperations: function (IDOperations) {
|
|
536
|
-
ReactDOMComponent.BackendIDOperations = BackendIDOperations = IDOperations;
|
|
537
|
-
}
|
|
538
|
-
};
|
|
539
|
-
|
|
540
909
|
module.exports = ReactDOMComponent;
|