react 0.8.0 → 0.9.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 +0 -8
- package/addons.js +0 -3
- package/lib/AutoFocusMixin.js +30 -0
- package/lib/CSSCore.js +22 -21
- package/lib/CSSProperty.js +31 -0
- package/lib/ChangeEventPlugin.js +26 -4
- package/lib/ClientReactRootIndex.js +30 -0
- package/lib/CompositionEventPlugin.js +57 -9
- package/lib/DOMChildrenOperations.js +32 -2
- package/lib/DOMProperty.js +2 -0
- package/lib/DOMPropertyOperations.js +14 -1
- package/lib/Danger.js +8 -7
- package/lib/DefaultDOMPropertyConfig.js +12 -2
- package/lib/EnterLeaveEventPlugin.js +37 -4
- package/lib/EventConstants.js +3 -0
- package/lib/EventListener.js +42 -34
- package/lib/EventPluginHub.js +113 -12
- package/lib/EventPluginRegistry.js +39 -16
- package/lib/EventPluginUtils.js +32 -3
- package/lib/EventPropagators.js +6 -42
- package/lib/ExecutionEnvironment.js +3 -0
- package/lib/LinkedValueUtils.js +161 -0
- package/lib/PooledClass.js +6 -0
- package/lib/React.js +27 -3
- package/lib/ReactCSSTransitionGroup.js +65 -0
- package/lib/{ReactTransitionableChild.js → ReactCSSTransitionGroupChild.js} +21 -35
- package/lib/ReactComponent.js +87 -52
- package/lib/ReactComponentBrowserEnvironment.js +67 -49
- package/lib/ReactComponentEnvironment.js +2 -0
- package/lib/ReactCompositeComponent.js +547 -112
- package/lib/ReactContext.js +67 -0
- package/lib/ReactDOM.js +13 -0
- package/lib/ReactDOMButton.js +4 -0
- package/lib/ReactDOMComponent.js +46 -21
- package/lib/ReactDOMForm.js +9 -2
- package/lib/ReactDOMIDOperations.js +105 -60
- package/lib/ReactDOMImg.js +58 -0
- package/lib/ReactDOMInput.js +26 -14
- package/lib/ReactDOMOption.js +1 -0
- package/lib/ReactDOMSelect.js +36 -17
- package/lib/ReactDOMTextarea.js +12 -8
- package/lib/ReactDefaultInjection.js +50 -26
- package/lib/ReactDefaultPerf.js +207 -370
- package/lib/ReactDefaultPerfAnalysis.js +199 -0
- package/lib/ReactErrorUtils.js +5 -14
- package/lib/ReactEventEmitter.js +141 -145
- package/lib/ReactEventEmitterMixin.js +0 -32
- package/lib/ReactEventTopLevelCallback.js +32 -12
- package/lib/ReactInjection.js +39 -0
- package/lib/ReactInstanceHandles.js +35 -19
- package/lib/ReactLink.js +1 -1
- package/lib/ReactMount.js +127 -103
- package/lib/ReactMountReady.js +1 -1
- package/lib/ReactMultiChild.js +30 -46
- package/lib/ReactMultiChildUpdateTypes.js +2 -0
- package/lib/ReactOwner.js +10 -2
- package/lib/ReactPerf.js +5 -8
- package/lib/ReactPropTransferer.js +40 -21
- package/lib/ReactPropTypeLocationNames.js +31 -0
- package/lib/ReactPropTypeLocations.js +29 -0
- package/lib/ReactPropTypes.js +248 -47
- package/lib/ReactPutListenerQueue.js +61 -0
- package/lib/ReactReconcileTransaction.js +20 -0
- package/lib/ReactRootIndex.js +36 -0
- package/lib/ReactServerRendering.js +8 -11
- package/lib/ReactTextComponent.js +8 -3
- package/lib/{ReactTransitionKeySet.js → ReactTransitionChildMapping.js} +42 -47
- package/lib/ReactTransitionGroup.js +132 -57
- package/lib/ReactUpdates.js +14 -11
- package/lib/ReactWithAddons.js +7 -2
- package/lib/SelectEventPlugin.js +22 -39
- package/lib/ServerReactRootIndex.js +36 -0
- package/lib/SimpleEventPlugin.js +54 -6
- package/lib/SyntheticClipboardEvent.js +7 -1
- package/lib/SyntheticDragEvent.js +44 -0
- package/lib/SyntheticEvent.js +2 -1
- package/lib/SyntheticKeyboardEvent.js +4 -2
- package/lib/SyntheticWheelEvent.js +10 -7
- package/lib/Transaction.js +61 -36
- package/lib/cloneWithProps.js +59 -0
- package/lib/createArrayFrom.js +10 -13
- package/lib/createFullPageComponent.js +63 -0
- package/lib/cx.js +2 -2
- package/lib/flattenChildren.js +5 -2
- package/lib/getActiveElement.js +4 -3
- package/lib/getEventKey.js +85 -0
- package/lib/getMarkupWrap.js +10 -0
- package/lib/getTextContentAccessor.js +5 -3
- package/lib/getUnboundedScrollPosition.js +2 -2
- package/lib/invariant.js +12 -4
- package/lib/isEventSupported.js +7 -11
- package/lib/mergeHelpers.js +5 -6
- package/lib/onlyChild.js +43 -0
- package/lib/shouldUpdateReactComponent.js +58 -0
- package/lib/toArray.js +75 -0
- package/lib/traverseAllChildren.js +69 -7
- package/lib/warning.js +40 -0
- package/package.json +2 -3
- package/react.js +0 -3
- package/ReactJSErrors.js +0 -40
- package/lib/$.js +0 -46
- package/lib/CallbackRegistry.js +0 -91
- package/lib/LinkedValueMixin.js +0 -68
- package/lib/ex.js +0 -49
- package/lib/filterAttributes.js +0 -45
- package/lib/ge.js +0 -76
- package/lib/mutateHTMLNodeWithMarkup.js +0 -100
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2013 Facebook, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*
|
|
16
|
+
* @providesModule ReactContext
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
"use strict";
|
|
20
|
+
|
|
21
|
+
var merge = require("./merge");
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Keeps track of the current context.
|
|
25
|
+
*
|
|
26
|
+
* The context is automatically passed down the component ownership hierarchy
|
|
27
|
+
* and is accessible via `this.context` on ReactCompositeComponents.
|
|
28
|
+
*/
|
|
29
|
+
var ReactContext = {
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @internal
|
|
33
|
+
* @type {object}
|
|
34
|
+
*/
|
|
35
|
+
current: {},
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Temporarily extends the current context while executing scopedCallback.
|
|
39
|
+
*
|
|
40
|
+
* A typical use case might look like
|
|
41
|
+
*
|
|
42
|
+
* render: function() {
|
|
43
|
+
* var children = ReactContext.withContext({foo: 'foo'} () => (
|
|
44
|
+
*
|
|
45
|
+
* ));
|
|
46
|
+
* return <div>{children}</div>;
|
|
47
|
+
* }
|
|
48
|
+
*
|
|
49
|
+
* @param {object} newContext New context to merge into the existing context
|
|
50
|
+
* @param {function} scopedCallback Callback to run with the new context
|
|
51
|
+
* @return {ReactComponent|array<ReactComponent>}
|
|
52
|
+
*/
|
|
53
|
+
withContext: function(newContext, scopedCallback) {
|
|
54
|
+
var result;
|
|
55
|
+
var previousContext = ReactContext.current;
|
|
56
|
+
ReactContext.current = merge(previousContext, newContext);
|
|
57
|
+
try {
|
|
58
|
+
result = scopedCallback();
|
|
59
|
+
} finally {
|
|
60
|
+
ReactContext.current = previousContext;
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
module.exports = ReactContext;
|
package/lib/ReactDOM.js
CHANGED
|
@@ -50,6 +50,14 @@ function createDOMComponentClass(tag, omitClose) {
|
|
|
50
50
|
instance.construct.apply(instance, arguments);
|
|
51
51
|
return instance;
|
|
52
52
|
};
|
|
53
|
+
|
|
54
|
+
// Expose the constructor on the ConvenienceConstructor and prototype so that
|
|
55
|
+
// it can be easily easily accessed on descriptors.
|
|
56
|
+
// E.g. <div />.type === div.type
|
|
57
|
+
ConvenienceConstructor.type = Constructor;
|
|
58
|
+
Constructor.prototype.type = Constructor;
|
|
59
|
+
|
|
60
|
+
Constructor.ConvenienceConstructor = ConvenienceConstructor;
|
|
53
61
|
ConvenienceConstructor.componentConstructor = Constructor;
|
|
54
62
|
return ConvenienceConstructor;
|
|
55
63
|
}
|
|
@@ -174,11 +182,16 @@ var ReactDOM = objMapKeyVal({
|
|
|
174
182
|
|
|
175
183
|
// SVG
|
|
176
184
|
circle: false,
|
|
185
|
+
defs: false,
|
|
177
186
|
g: false,
|
|
178
187
|
line: false,
|
|
188
|
+
linearGradient: false,
|
|
179
189
|
path: false,
|
|
190
|
+
polygon: false,
|
|
180
191
|
polyline: false,
|
|
192
|
+
radialGradient: false,
|
|
181
193
|
rect: false,
|
|
194
|
+
stop: false,
|
|
182
195
|
svg: false,
|
|
183
196
|
text: false
|
|
184
197
|
}, createDOMComponentClass);
|
package/lib/ReactDOMButton.js
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
"use strict";
|
|
20
20
|
|
|
21
|
+
var AutoFocusMixin = require("./AutoFocusMixin");
|
|
21
22
|
var ReactCompositeComponent = require("./ReactCompositeComponent");
|
|
22
23
|
var ReactDOM = require("./ReactDOM");
|
|
23
24
|
|
|
@@ -44,6 +45,9 @@ var mouseListenerNames = keyMirror({
|
|
|
44
45
|
* when `disabled` is set.
|
|
45
46
|
*/
|
|
46
47
|
var ReactDOMButton = ReactCompositeComponent.createClass({
|
|
48
|
+
displayName: 'ReactDOMButton',
|
|
49
|
+
|
|
50
|
+
mixins: [AutoFocusMixin],
|
|
47
51
|
|
|
48
52
|
render: function() {
|
|
49
53
|
var props = {};
|
package/lib/ReactDOMComponent.js
CHANGED
|
@@ -24,8 +24,8 @@ var DOMProperty = require("./DOMProperty");
|
|
|
24
24
|
var DOMPropertyOperations = require("./DOMPropertyOperations");
|
|
25
25
|
var ReactComponent = require("./ReactComponent");
|
|
26
26
|
var ReactEventEmitter = require("./ReactEventEmitter");
|
|
27
|
-
var ReactMultiChild = require("./ReactMultiChild");
|
|
28
27
|
var ReactMount = require("./ReactMount");
|
|
28
|
+
var ReactMultiChild = require("./ReactMultiChild");
|
|
29
29
|
var ReactPerf = require("./ReactPerf");
|
|
30
30
|
|
|
31
31
|
var escapeTextForBrowser = require("./escapeTextForBrowser");
|
|
@@ -34,15 +34,17 @@ var keyOf = require("./keyOf");
|
|
|
34
34
|
var merge = require("./merge");
|
|
35
35
|
var mixInto = require("./mixInto");
|
|
36
36
|
|
|
37
|
-
var putListener = ReactEventEmitter.putListener;
|
|
38
37
|
var deleteListener = ReactEventEmitter.deleteListener;
|
|
39
|
-
var
|
|
38
|
+
var listenTo = ReactEventEmitter.listenTo;
|
|
39
|
+
var registrationNameModules = ReactEventEmitter.registrationNameModules;
|
|
40
40
|
|
|
41
41
|
// For quickly matching children type, to test if can be treated as content.
|
|
42
42
|
var CONTENT_TYPES = {'string': true, 'number': true};
|
|
43
43
|
|
|
44
44
|
var STYLE = keyOf({style: null});
|
|
45
45
|
|
|
46
|
+
var ELEMENT_NODE_TYPE = 1;
|
|
47
|
+
|
|
46
48
|
/**
|
|
47
49
|
* @param {?object} props
|
|
48
50
|
*/
|
|
@@ -62,6 +64,22 @@ function assertValidProps(props) {
|
|
|
62
64
|
) : invariant(props.style == null || typeof props.style === 'object'));
|
|
63
65
|
}
|
|
64
66
|
|
|
67
|
+
function putListener(id, registrationName, listener, transaction) {
|
|
68
|
+
var container = ReactMount.findReactContainerForID(id);
|
|
69
|
+
if (container) {
|
|
70
|
+
var doc = container.nodeType === ELEMENT_NODE_TYPE ?
|
|
71
|
+
container.ownerDocument :
|
|
72
|
+
container;
|
|
73
|
+
listenTo(registrationName, doc);
|
|
74
|
+
}
|
|
75
|
+
transaction.getPutListenerQueue().enqueuePutListener(
|
|
76
|
+
id,
|
|
77
|
+
registrationName,
|
|
78
|
+
listener
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
|
|
65
83
|
/**
|
|
66
84
|
* @constructor ReactDOMComponent
|
|
67
85
|
* @extends ReactComponent
|
|
@@ -97,7 +115,7 @@ ReactDOMComponent.Mixin = {
|
|
|
97
115
|
);
|
|
98
116
|
assertValidProps(this.props);
|
|
99
117
|
return (
|
|
100
|
-
this.
|
|
118
|
+
this._createOpenTagMarkupAndPutListeners(transaction) +
|
|
101
119
|
this._createContentMarkup(transaction) +
|
|
102
120
|
this._tagClose
|
|
103
121
|
);
|
|
@@ -113,9 +131,10 @@ ReactDOMComponent.Mixin = {
|
|
|
113
131
|
* @see http://jsperf.com/obj-vs-arr-iteration
|
|
114
132
|
*
|
|
115
133
|
* @private
|
|
134
|
+
* @param {ReactReconcileTransaction} transaction
|
|
116
135
|
* @return {string} Markup of opening tag.
|
|
117
136
|
*/
|
|
118
|
-
|
|
137
|
+
_createOpenTagMarkupAndPutListeners: function(transaction) {
|
|
119
138
|
var props = this.props;
|
|
120
139
|
var ret = this._tagOpen;
|
|
121
140
|
|
|
@@ -127,8 +146,8 @@ ReactDOMComponent.Mixin = {
|
|
|
127
146
|
if (propValue == null) {
|
|
128
147
|
continue;
|
|
129
148
|
}
|
|
130
|
-
if (
|
|
131
|
-
putListener(this._rootNodeID, propKey, propValue);
|
|
149
|
+
if (registrationNameModules[propKey]) {
|
|
150
|
+
putListener(this._rootNodeID, propKey, propValue, transaction);
|
|
132
151
|
} else {
|
|
133
152
|
if (propKey === STYLE) {
|
|
134
153
|
if (propValue) {
|
|
@@ -144,8 +163,8 @@ ReactDOMComponent.Mixin = {
|
|
|
144
163
|
}
|
|
145
164
|
}
|
|
146
165
|
|
|
147
|
-
var
|
|
148
|
-
return ret + ' ' +
|
|
166
|
+
var idMarkup = DOMPropertyOperations.createMarkupForID(this._rootNodeID);
|
|
167
|
+
return ret + ' ' + idMarkup + '>';
|
|
149
168
|
},
|
|
150
169
|
|
|
151
170
|
/**
|
|
@@ -200,9 +219,14 @@ ReactDOMComponent.Mixin = {
|
|
|
200
219
|
updateComponent: ReactPerf.measure(
|
|
201
220
|
'ReactDOMComponent',
|
|
202
221
|
'updateComponent',
|
|
203
|
-
function(transaction, prevProps) {
|
|
204
|
-
ReactComponent.Mixin.updateComponent.call(
|
|
205
|
-
|
|
222
|
+
function(transaction, prevProps, prevOwner) {
|
|
223
|
+
ReactComponent.Mixin.updateComponent.call(
|
|
224
|
+
this,
|
|
225
|
+
transaction,
|
|
226
|
+
prevProps,
|
|
227
|
+
prevOwner
|
|
228
|
+
);
|
|
229
|
+
this._updateDOMProperties(prevProps, transaction);
|
|
206
230
|
this._updateDOMChildren(prevProps, transaction);
|
|
207
231
|
}
|
|
208
232
|
),
|
|
@@ -220,8 +244,9 @@ ReactDOMComponent.Mixin = {
|
|
|
220
244
|
*
|
|
221
245
|
* @private
|
|
222
246
|
* @param {object} lastProps
|
|
247
|
+
* @param {ReactReconcileTransaction} transaction
|
|
223
248
|
*/
|
|
224
|
-
_updateDOMProperties: function(lastProps) {
|
|
249
|
+
_updateDOMProperties: function(lastProps, transaction) {
|
|
225
250
|
var nextProps = this.props;
|
|
226
251
|
var propKey;
|
|
227
252
|
var styleName;
|
|
@@ -239,12 +264,12 @@ ReactDOMComponent.Mixin = {
|
|
|
239
264
|
styleUpdates[styleName] = '';
|
|
240
265
|
}
|
|
241
266
|
}
|
|
242
|
-
} else if (
|
|
267
|
+
} else if (registrationNameModules[propKey]) {
|
|
243
268
|
deleteListener(this._rootNodeID, propKey);
|
|
244
269
|
} else if (
|
|
245
270
|
DOMProperty.isStandardName[propKey] ||
|
|
246
271
|
DOMProperty.isCustomAttribute(propKey)) {
|
|
247
|
-
ReactComponent.
|
|
272
|
+
ReactComponent.BackendIDOperations.deletePropertyByID(
|
|
248
273
|
this._rootNodeID,
|
|
249
274
|
propKey
|
|
250
275
|
);
|
|
@@ -281,12 +306,12 @@ ReactDOMComponent.Mixin = {
|
|
|
281
306
|
// Relies on `updateStylesByID` not mutating `styleUpdates`.
|
|
282
307
|
styleUpdates = nextProp;
|
|
283
308
|
}
|
|
284
|
-
} else if (
|
|
285
|
-
putListener(this._rootNodeID, propKey, nextProp);
|
|
309
|
+
} else if (registrationNameModules[propKey]) {
|
|
310
|
+
putListener(this._rootNodeID, propKey, nextProp, transaction);
|
|
286
311
|
} else if (
|
|
287
312
|
DOMProperty.isStandardName[propKey] ||
|
|
288
313
|
DOMProperty.isCustomAttribute(propKey)) {
|
|
289
|
-
ReactComponent.
|
|
314
|
+
ReactComponent.BackendIDOperations.updatePropertyByID(
|
|
290
315
|
this._rootNodeID,
|
|
291
316
|
propKey,
|
|
292
317
|
nextProp
|
|
@@ -294,7 +319,7 @@ ReactDOMComponent.Mixin = {
|
|
|
294
319
|
}
|
|
295
320
|
}
|
|
296
321
|
if (styleUpdates) {
|
|
297
|
-
ReactComponent.
|
|
322
|
+
ReactComponent.BackendIDOperations.updateStylesByID(
|
|
298
323
|
this._rootNodeID,
|
|
299
324
|
styleUpdates
|
|
300
325
|
);
|
|
@@ -343,7 +368,7 @@ ReactDOMComponent.Mixin = {
|
|
|
343
368
|
}
|
|
344
369
|
} else if (nextHtml != null) {
|
|
345
370
|
if (lastHtml !== nextHtml) {
|
|
346
|
-
ReactComponent.
|
|
371
|
+
ReactComponent.BackendIDOperations.updateInnerHTMLByID(
|
|
347
372
|
this._rootNodeID,
|
|
348
373
|
nextHtml
|
|
349
374
|
);
|
|
@@ -360,9 +385,9 @@ ReactDOMComponent.Mixin = {
|
|
|
360
385
|
* @internal
|
|
361
386
|
*/
|
|
362
387
|
unmountComponent: function() {
|
|
388
|
+
this.unmountChildren();
|
|
363
389
|
ReactEventEmitter.deleteAllListeners(this._rootNodeID);
|
|
364
390
|
ReactComponent.Mixin.unmountComponent.call(this);
|
|
365
|
-
this.unmountChildren();
|
|
366
391
|
}
|
|
367
392
|
|
|
368
393
|
};
|
package/lib/ReactDOMForm.js
CHANGED
|
@@ -33,6 +33,8 @@ var form = ReactDOM.form;
|
|
|
33
33
|
* composite component and use `componentDidMount` to attach the event handlers.
|
|
34
34
|
*/
|
|
35
35
|
var ReactDOMForm = ReactCompositeComponent.createClass({
|
|
36
|
+
displayName: 'ReactDOMForm',
|
|
37
|
+
|
|
36
38
|
render: function() {
|
|
37
39
|
// TODO: Instead of using `ReactDOM` directly, we should use JSX. However,
|
|
38
40
|
// `jshint` fails to parse JSX so in order for linting to work in the open
|
|
@@ -40,11 +42,16 @@ var ReactDOMForm = ReactCompositeComponent.createClass({
|
|
|
40
42
|
return this.transferPropsTo(form(null, this.props.children));
|
|
41
43
|
},
|
|
42
44
|
|
|
43
|
-
componentDidMount: function(
|
|
45
|
+
componentDidMount: function() {
|
|
46
|
+
ReactEventEmitter.trapBubbledEvent(
|
|
47
|
+
EventConstants.topLevelTypes.topReset,
|
|
48
|
+
'reset',
|
|
49
|
+
this.getDOMNode()
|
|
50
|
+
);
|
|
44
51
|
ReactEventEmitter.trapBubbledEvent(
|
|
45
52
|
EventConstants.topLevelTypes.topSubmit,
|
|
46
53
|
'submit',
|
|
47
|
-
|
|
54
|
+
this.getDOMNode()
|
|
48
55
|
);
|
|
49
56
|
}
|
|
50
57
|
});
|
|
@@ -25,8 +25,8 @@ var CSSPropertyOperations = require("./CSSPropertyOperations");
|
|
|
25
25
|
var DOMChildrenOperations = require("./DOMChildrenOperations");
|
|
26
26
|
var DOMPropertyOperations = require("./DOMPropertyOperations");
|
|
27
27
|
var ReactMount = require("./ReactMount");
|
|
28
|
+
var ReactPerf = require("./ReactPerf");
|
|
28
29
|
|
|
29
|
-
var getTextContentAccessor = require("./getTextContentAccessor");
|
|
30
30
|
var invariant = require("./invariant");
|
|
31
31
|
|
|
32
32
|
/**
|
|
@@ -41,19 +41,11 @@ var INVALID_PROPERTY_ERRORS = {
|
|
|
41
41
|
style: '`style` must be set using `updateStylesByID()`.'
|
|
42
42
|
};
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
* The DOM property to use when setting text content.
|
|
46
|
-
*
|
|
47
|
-
* @type {string}
|
|
48
|
-
* @private
|
|
49
|
-
*/
|
|
50
|
-
var textContentAccessor = getTextContentAccessor() || 'NA';
|
|
51
|
-
|
|
52
|
-
var LEADING_SPACE = /^ /;
|
|
44
|
+
var useWhitespaceWorkaround;
|
|
53
45
|
|
|
54
46
|
/**
|
|
55
47
|
* Operations used to process updates to DOM nodes. This is made injectable via
|
|
56
|
-
* `ReactComponent.
|
|
48
|
+
* `ReactComponent.BackendIDOperations`.
|
|
57
49
|
*/
|
|
58
50
|
var ReactDOMIDOperations = {
|
|
59
51
|
|
|
@@ -66,23 +58,27 @@ var ReactDOMIDOperations = {
|
|
|
66
58
|
* @param {*} value New value of the property.
|
|
67
59
|
* @internal
|
|
68
60
|
*/
|
|
69
|
-
updatePropertyByID:
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
61
|
+
updatePropertyByID: ReactPerf.measure(
|
|
62
|
+
'ReactDOMIDOperations',
|
|
63
|
+
'updatePropertyByID',
|
|
64
|
+
function(id, name, value) {
|
|
65
|
+
var node = ReactMount.getNode(id);
|
|
66
|
+
("production" !== process.env.NODE_ENV ? invariant(
|
|
67
|
+
!INVALID_PROPERTY_ERRORS.hasOwnProperty(name),
|
|
68
|
+
'updatePropertyByID(...): %s',
|
|
69
|
+
INVALID_PROPERTY_ERRORS[name]
|
|
70
|
+
) : invariant(!INVALID_PROPERTY_ERRORS.hasOwnProperty(name)));
|
|
71
|
+
|
|
72
|
+
// If we're updating to null or undefined, we should remove the property
|
|
73
|
+
// from the DOM node instead of inadvertantly setting to a string. This
|
|
74
|
+
// brings us in line with the same behavior we have on initial render.
|
|
75
|
+
if (value != null) {
|
|
76
|
+
DOMPropertyOperations.setValueForProperty(node, name, value);
|
|
77
|
+
} else {
|
|
78
|
+
DOMPropertyOperations.deleteValueForProperty(node, name);
|
|
79
|
+
}
|
|
84
80
|
}
|
|
85
|
-
|
|
81
|
+
),
|
|
86
82
|
|
|
87
83
|
/**
|
|
88
84
|
* Updates a DOM node to remove a property. This should only be used to remove
|
|
@@ -92,15 +88,19 @@ var ReactDOMIDOperations = {
|
|
|
92
88
|
* @param {string} name A property name to remove, see `DOMProperty`.
|
|
93
89
|
* @internal
|
|
94
90
|
*/
|
|
95
|
-
deletePropertyByID:
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
91
|
+
deletePropertyByID: ReactPerf.measure(
|
|
92
|
+
'ReactDOMIDOperations',
|
|
93
|
+
'deletePropertyByID',
|
|
94
|
+
function(id, name, value) {
|
|
95
|
+
var node = ReactMount.getNode(id);
|
|
96
|
+
("production" !== process.env.NODE_ENV ? invariant(
|
|
97
|
+
!INVALID_PROPERTY_ERRORS.hasOwnProperty(name),
|
|
98
|
+
'updatePropertyByID(...): %s',
|
|
99
|
+
INVALID_PROPERTY_ERRORS[name]
|
|
100
|
+
) : invariant(!INVALID_PROPERTY_ERRORS.hasOwnProperty(name)));
|
|
101
|
+
DOMPropertyOperations.deleteValueForProperty(node, name, value);
|
|
102
|
+
}
|
|
103
|
+
),
|
|
104
104
|
|
|
105
105
|
/**
|
|
106
106
|
* Updates a DOM node with new style values. If a value is specified as '',
|
|
@@ -110,10 +110,14 @@ var ReactDOMIDOperations = {
|
|
|
110
110
|
* @param {object} styles Mapping from styles to values.
|
|
111
111
|
* @internal
|
|
112
112
|
*/
|
|
113
|
-
updateStylesByID:
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
113
|
+
updateStylesByID: ReactPerf.measure(
|
|
114
|
+
'ReactDOMIDOperations',
|
|
115
|
+
'updateStylesByID',
|
|
116
|
+
function(id, styles) {
|
|
117
|
+
var node = ReactMount.getNode(id);
|
|
118
|
+
CSSPropertyOperations.setValueForStyles(node, styles);
|
|
119
|
+
}
|
|
120
|
+
),
|
|
117
121
|
|
|
118
122
|
/**
|
|
119
123
|
* Updates a DOM node's innerHTML.
|
|
@@ -122,12 +126,42 @@ var ReactDOMIDOperations = {
|
|
|
122
126
|
* @param {string} html An HTML string.
|
|
123
127
|
* @internal
|
|
124
128
|
*/
|
|
125
|
-
updateInnerHTMLByID:
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
129
|
+
updateInnerHTMLByID: ReactPerf.measure(
|
|
130
|
+
'ReactDOMIDOperations',
|
|
131
|
+
'updateInnerHTMLByID',
|
|
132
|
+
function(id, html) {
|
|
133
|
+
var node = ReactMount.getNode(id);
|
|
134
|
+
|
|
135
|
+
// IE8: When updating a just created node with innerHTML only leading
|
|
136
|
+
// whitespace is removed. When updating an existing node with innerHTML
|
|
137
|
+
// whitespace in root TextNodes is also collapsed.
|
|
138
|
+
// @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html
|
|
139
|
+
|
|
140
|
+
if (useWhitespaceWorkaround === undefined) {
|
|
141
|
+
// Feature detection; only IE8 is known to behave improperly like this.
|
|
142
|
+
var temp = document.createElement('div');
|
|
143
|
+
temp.innerHTML = ' ';
|
|
144
|
+
useWhitespaceWorkaround = temp.innerHTML === '';
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (useWhitespaceWorkaround) {
|
|
148
|
+
// Magic theory: IE8 supposedly differentiates between added and updated
|
|
149
|
+
// nodes when processing innerHTML, innerHTML on updated nodes suffers
|
|
150
|
+
// from worse whitespace behavior. Re-adding a node like this triggers
|
|
151
|
+
// the initial and more favorable whitespace behavior.
|
|
152
|
+
node.parentNode.replaceChild(node, node);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (useWhitespaceWorkaround && html.match(/^[ \r\n\t\f]/)) {
|
|
156
|
+
// Recover leading whitespace by temporarily prepending any character.
|
|
157
|
+
// \uFEFF has the potential advantage of being zero-width/invisible.
|
|
158
|
+
node.innerHTML = '\uFEFF' + html;
|
|
159
|
+
node.firstChild.deleteData(0, 1);
|
|
160
|
+
} else {
|
|
161
|
+
node.innerHTML = html;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
),
|
|
131
165
|
|
|
132
166
|
/**
|
|
133
167
|
* Updates a DOM node's text content set by `props.content`.
|
|
@@ -136,10 +170,14 @@ var ReactDOMIDOperations = {
|
|
|
136
170
|
* @param {string} content Text content.
|
|
137
171
|
* @internal
|
|
138
172
|
*/
|
|
139
|
-
updateTextContentByID:
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
173
|
+
updateTextContentByID: ReactPerf.measure(
|
|
174
|
+
'ReactDOMIDOperations',
|
|
175
|
+
'updateTextContentByID',
|
|
176
|
+
function(id, content) {
|
|
177
|
+
var node = ReactMount.getNode(id);
|
|
178
|
+
DOMChildrenOperations.updateTextContent(node, content);
|
|
179
|
+
}
|
|
180
|
+
),
|
|
143
181
|
|
|
144
182
|
/**
|
|
145
183
|
* Replaces a DOM node that exists in the document with markup.
|
|
@@ -149,10 +187,14 @@ var ReactDOMIDOperations = {
|
|
|
149
187
|
* @internal
|
|
150
188
|
* @see {Danger.dangerouslyReplaceNodeWithMarkup}
|
|
151
189
|
*/
|
|
152
|
-
dangerouslyReplaceNodeWithMarkupByID:
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
190
|
+
dangerouslyReplaceNodeWithMarkupByID: ReactPerf.measure(
|
|
191
|
+
'ReactDOMIDOperations',
|
|
192
|
+
'dangerouslyReplaceNodeWithMarkupByID',
|
|
193
|
+
function(id, markup) {
|
|
194
|
+
var node = ReactMount.getNode(id);
|
|
195
|
+
DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup(node, markup);
|
|
196
|
+
}
|
|
197
|
+
),
|
|
156
198
|
|
|
157
199
|
/**
|
|
158
200
|
* Updates a component's children by processing a series of updates.
|
|
@@ -161,13 +203,16 @@ var ReactDOMIDOperations = {
|
|
|
161
203
|
* @param {array<string>} markup List of markup strings.
|
|
162
204
|
* @internal
|
|
163
205
|
*/
|
|
164
|
-
dangerouslyProcessChildrenUpdates:
|
|
165
|
-
|
|
166
|
-
|
|
206
|
+
dangerouslyProcessChildrenUpdates: ReactPerf.measure(
|
|
207
|
+
'ReactDOMIDOperations',
|
|
208
|
+
'dangerouslyProcessChildrenUpdates',
|
|
209
|
+
function(updates, markup) {
|
|
210
|
+
for (var i = 0; i < updates.length; i++) {
|
|
211
|
+
updates[i].parentNode = ReactMount.getNode(updates[i].parentID);
|
|
212
|
+
}
|
|
213
|
+
DOMChildrenOperations.processUpdates(updates, markup);
|
|
167
214
|
}
|
|
168
|
-
|
|
169
|
-
}
|
|
170
|
-
|
|
215
|
+
)
|
|
171
216
|
};
|
|
172
217
|
|
|
173
218
|
module.exports = ReactDOMIDOperations;
|