react 0.13.0 → 0.14.0-alpha1
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 +1 -1
- package/addons.js +7 -0
- package/addons/CSSTransitionGroup.js +1 -0
- package/addons/LinkedStateMixin.js +1 -0
- package/addons/Perf.js +1 -0
- package/addons/PureRenderMixin.js +1 -0
- package/addons/TestUtils.js +1 -0
- package/addons/TransitionGroup.js +1 -0
- package/addons/batchedUpdates.js +1 -0
- package/addons/cloneWithProps.js +1 -0
- package/addons/createFragment.js +1 -0
- package/addons/renderSubtreeIntoContainer.js +1 -0
- package/addons/shallowCompare.js +1 -0
- package/addons/update.js +1 -0
- package/dist/JSXTransformer.js +3336 -1671
- package/dist/react-with-addons.js +3134 -5113
- package/dist/react-with-addons.min.js +6 -6
- package/dist/react.js +2812 -4567
- package/dist/react.min.js +5 -5
- package/lib/AutoFocusMixin.js +4 -3
- package/lib/BeforeInputEventPlugin.js +30 -118
- package/lib/CSSCore.js +12 -23
- package/lib/CSSProperty.js +9 -4
- package/lib/CSSPropertyOperations.js +14 -30
- package/lib/CallbackQueue.js +7 -10
- package/lib/ChangeEventPlugin.js +24 -88
- package/lib/ClientReactRootIndex.js +2 -2
- package/lib/DOMChildrenOperations.js +13 -33
- package/lib/DOMProperty.js +41 -65
- package/lib/DOMPropertyOperations.js +30 -51
- package/lib/Danger.js +19 -60
- package/lib/DefaultEventPluginOrder.js +2 -12
- package/lib/EnterLeaveEventPlugin.js +11 -33
- package/lib/EventConstants.js +2 -2
- package/lib/EventListener.js +11 -13
- package/lib/EventPluginHub.js +44 -47
- package/lib/EventPluginRegistry.js +18 -74
- package/lib/EventPluginUtils.js +27 -38
- package/lib/EventPropagators.js +23 -26
- package/lib/ExecutionEnvironment.js +4 -8
- package/lib/FallbackCompositionState.js +3 -3
- package/lib/HTMLDOMPropertyConfig.js +12 -18
- package/lib/LinkedStateMixin.js +3 -6
- package/lib/LinkedValueUtils.js +34 -64
- package/lib/LocalEventTrapMixin.js +9 -16
- package/lib/Object.assign.js +1 -1
- package/lib/PooledClass.js +8 -11
- package/lib/React.js +20 -38
- package/lib/ReactBrowserComponentMixin.js +9 -2
- package/lib/ReactBrowserEventEmitter.js +26 -82
- package/lib/ReactCSSTransitionGroup.js +13 -24
- package/lib/ReactCSSTransitionGroupChild.js +18 -28
- package/lib/ReactChildReconciler.js +11 -19
- package/lib/ReactChildren.js +7 -16
- package/lib/ReactClass.js +78 -231
- package/lib/ReactComponent.js +17 -33
- package/lib/ReactComponentBrowserEnvironment.js +4 -6
- package/lib/ReactComponentEnvironment.js +6 -12
- package/lib/ReactComponentWithPureRenderMixin.js +4 -5
- package/lib/ReactCompositeComponent.js +85 -297
- package/lib/ReactContext.js +2 -44
- package/lib/ReactCurrentOwner.js +1 -3
- package/lib/ReactDOM.js +4 -2
- package/lib/ReactDOMButton.js +3 -4
- package/lib/ReactDOMComponent.js +185 -146
- package/lib/ReactDOMForm.js +3 -3
- package/lib/ReactDOMIDOperations.js +11 -20
- package/lib/ReactDOMIframe.js +3 -3
- package/lib/ReactDOMImg.js +3 -3
- package/lib/ReactDOMInput.js +22 -35
- package/lib/ReactDOMOption.js +52 -10
- package/lib/ReactDOMSelect.js +53 -29
- package/lib/ReactDOMSelection.js +5 -20
- package/lib/ReactDOMTextComponent.js +17 -18
- package/lib/ReactDOMTextarea.js +15 -27
- package/lib/ReactDefaultBatchingStrategy.js +9 -13
- package/lib/ReactDefaultInjection.js +21 -40
- package/lib/ReactDefaultPerf.js +41 -72
- package/lib/ReactDefaultPerfAnalysis.js +8 -14
- package/lib/ReactElement.js +35 -72
- package/lib/ReactElementValidator.js +51 -110
- package/lib/ReactEmptyComponent.js +7 -11
- package/lib/ReactErrorUtils.js +2 -2
- package/lib/ReactEventEmitterMixin.js +3 -12
- package/lib/ReactEventListener.js +16 -38
- package/lib/ReactFragment.js +23 -54
- package/lib/ReactInjection.js +1 -1
- package/lib/ReactInputSelection.js +11 -21
- package/lib/ReactInstanceHandles.js +27 -57
- package/lib/ReactInstanceMap.js +5 -5
- package/lib/ReactLifeCycle.js +1 -1
- package/lib/ReactLink.js +2 -4
- package/lib/ReactMarkupChecksum.js +5 -10
- package/lib/ReactMount.js +136 -260
- package/lib/ReactMultiChild.js +19 -45
- package/lib/ReactMultiChildUpdateTypes.js +1 -1
- package/lib/ReactNativeComponent.js +7 -11
- package/lib/ReactOwner.js +7 -24
- package/lib/ReactPerf.js +8 -12
- package/lib/ReactPropTransferer.js +4 -4
- package/lib/ReactPropTypeLocationNames.js +2 -2
- package/lib/ReactPropTypeLocations.js +1 -1
- package/lib/ReactPropTypes.js +13 -46
- package/lib/ReactReconcileTransaction.js +9 -34
- package/lib/ReactReconciler.js +9 -19
- package/lib/ReactRef.js +5 -8
- package/lib/ReactRootIndex.js +2 -2
- package/lib/ReactServerRendering.js +7 -15
- package/lib/ReactServerRenderingTransaction.js +7 -32
- package/lib/ReactStateSetters.js +6 -6
- package/lib/ReactTestUtils.js +94 -166
- package/lib/ReactTransitionChildMapping.js +5 -7
- package/lib/ReactTransitionEvents.js +5 -5
- package/lib/ReactTransitionGroup.js +30 -52
- package/lib/ReactUpdateQueue.js +27 -90
- package/lib/ReactUpdates.js +27 -79
- package/lib/ReactWithAddons.js +7 -6
- package/lib/SVGDOMPropertyConfig.js +41 -2
- package/lib/SelectEventPlugin.js +28 -29
- package/lib/ServerReactRootIndex.js +2 -2
- package/lib/SimpleEventPlugin.js +136 -128
- package/lib/SyntheticClipboardEvent.js +3 -7
- package/lib/SyntheticCompositionEvent.js +3 -9
- package/lib/SyntheticDragEvent.js +1 -1
- package/lib/SyntheticEvent.js +8 -10
- package/lib/SyntheticFocusEvent.js +1 -1
- package/lib/SyntheticInputEvent.js +3 -9
- package/lib/SyntheticKeyboardEvent.js +4 -4
- package/lib/SyntheticMouseEvent.js +8 -14
- package/lib/SyntheticTouchEvent.js +1 -1
- package/lib/SyntheticUIEvent.js +3 -3
- package/lib/SyntheticWheelEvent.js +11 -15
- package/lib/Transaction.js +12 -24
- package/lib/ViewportMetrics.js +2 -2
- package/lib/accumulateInto.js +2 -5
- package/lib/adler32.js +2 -2
- package/lib/camelize.js +4 -2
- package/lib/camelizeStyleName.js +2 -2
- package/lib/cloneWithProps.js +5 -11
- package/lib/containsNode.js +29 -16
- package/lib/createArrayFromMixed.js +17 -16
- package/lib/createFullPageComponent.js +5 -11
- package/lib/createNodesFromMarkup.js +6 -8
- package/lib/dangerousStyleValue.js +2 -3
- package/lib/emptyFunction.js +10 -4
- package/lib/emptyObject.js +1 -1
- package/lib/escapeTextContentForBrowser.js +1 -1
- package/lib/findDOMNode.js +5 -24
- package/lib/flattenChildren.js +4 -10
- package/lib/focusNode.js +2 -3
- package/lib/forEachAccumulated.js +2 -2
- package/lib/getActiveElement.js +4 -2
- package/lib/getEventCharCode.js +1 -1
- package/lib/getEventKey.js +1 -1
- package/lib/getEventModifierState.js +1 -1
- package/lib/getEventTarget.js +1 -1
- package/lib/getIteratorFn.js +2 -4
- package/lib/getMarkupWrap.js +7 -5
- package/lib/getNodeForCharacterOffset.js +1 -1
- package/lib/getTextContentAccessor.js +2 -4
- package/lib/getUnboundedScrollPosition.js +1 -1
- package/lib/hyphenate.js +3 -1
- package/lib/hyphenateStyleName.js +2 -2
- package/lib/instantiateReactComponent.js +14 -37
- package/lib/invariant.js +8 -12
- package/lib/isEventSupported.js +7 -10
- package/lib/isNode.js +4 -6
- package/lib/isTextInputElement.js +2 -4
- package/lib/isTextNode.js +3 -1
- package/lib/joinClasses.js +2 -2
- package/lib/keyMirror.js +3 -6
- package/lib/keyOf.js +4 -3
- package/lib/mapObject.js +1 -1
- package/lib/memoizeStringOnly.js +2 -2
- package/lib/onlyChild.js +2 -5
- package/lib/performance.js +2 -5
- package/lib/performanceNow.js +3 -1
- package/lib/quoteAttributeValueForBrowser.js +1 -1
- package/lib/renderSubtreeIntoContainer.js +16 -0
- package/lib/setInnerHTML.js +11 -8
- package/lib/setTextContent.js +3 -3
- package/lib/shallowCompare.js +24 -0
- package/lib/shallowEqual.js +17 -11
- package/lib/shouldUpdateReactComponent.js +3 -64
- package/lib/toArray.js +8 -19
- package/lib/traverseAllChildren.js +19 -82
- package/lib/update.js +33 -90
- package/lib/validateDOMNesting.js +264 -0
- package/lib/warning.js +17 -15
- package/package.json +3 -3
- package/lib/MobileSafariClickEventPlugin.js +0 -56
- package/lib/ReactPutListenerQueue.js +0 -54
- package/lib/cx.js +0 -52
- package/lib/getReactRootElementInContainer.js +0 -33
package/lib/update.js
CHANGED
|
@@ -9,11 +9,14 @@
|
|
|
9
9
|
* @providesModule update
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
+
/* global hasOwnProperty:true */
|
|
13
|
+
|
|
12
14
|
'use strict';
|
|
13
15
|
|
|
14
16
|
var assign = require("./Object.assign");
|
|
15
17
|
var keyOf = require("./keyOf");
|
|
16
18
|
var invariant = require("./invariant");
|
|
19
|
+
var hasOwnProperty = ({}).hasOwnProperty;
|
|
17
20
|
|
|
18
21
|
function shallowCopy(x) {
|
|
19
22
|
if (Array.isArray(x)) {
|
|
@@ -25,130 +28,70 @@ function shallowCopy(x) {
|
|
|
25
28
|
}
|
|
26
29
|
}
|
|
27
30
|
|
|
28
|
-
var COMMAND_PUSH = keyOf({$push: null});
|
|
29
|
-
var COMMAND_UNSHIFT = keyOf({$unshift: null});
|
|
30
|
-
var COMMAND_SPLICE = keyOf({$splice: null});
|
|
31
|
-
var COMMAND_SET = keyOf({$set: null});
|
|
32
|
-
var COMMAND_MERGE = keyOf({$merge: null});
|
|
33
|
-
var COMMAND_APPLY = keyOf({$apply: null});
|
|
34
|
-
|
|
35
|
-
var ALL_COMMANDS_LIST = [
|
|
36
|
-
COMMAND_PUSH,
|
|
37
|
-
COMMAND_UNSHIFT,
|
|
38
|
-
COMMAND_SPLICE,
|
|
39
|
-
COMMAND_SET,
|
|
40
|
-
COMMAND_MERGE,
|
|
41
|
-
COMMAND_APPLY
|
|
42
|
-
];
|
|
31
|
+
var COMMAND_PUSH = keyOf({ $push: null });
|
|
32
|
+
var COMMAND_UNSHIFT = keyOf({ $unshift: null });
|
|
33
|
+
var COMMAND_SPLICE = keyOf({ $splice: null });
|
|
34
|
+
var COMMAND_SET = keyOf({ $set: null });
|
|
35
|
+
var COMMAND_MERGE = keyOf({ $merge: null });
|
|
36
|
+
var COMMAND_APPLY = keyOf({ $apply: null });
|
|
37
|
+
|
|
38
|
+
var ALL_COMMANDS_LIST = [COMMAND_PUSH, COMMAND_UNSHIFT, COMMAND_SPLICE, COMMAND_SET, COMMAND_MERGE, COMMAND_APPLY];
|
|
43
39
|
|
|
44
40
|
var ALL_COMMANDS_SET = {};
|
|
45
41
|
|
|
46
|
-
ALL_COMMANDS_LIST.forEach(function(command) {
|
|
42
|
+
ALL_COMMANDS_LIST.forEach(function (command) {
|
|
47
43
|
ALL_COMMANDS_SET[command] = true;
|
|
48
44
|
});
|
|
49
45
|
|
|
50
46
|
function invariantArrayCase(value, spec, command) {
|
|
51
|
-
|
|
52
|
-
Array.isArray(value),
|
|
53
|
-
'update(): expected target of %s to be an array; got %s.',
|
|
54
|
-
command,
|
|
55
|
-
value
|
|
56
|
-
) : invariant(Array.isArray(value)));
|
|
47
|
+
'production' !== process.env.NODE_ENV ? invariant(Array.isArray(value), 'update(): expected target of %s to be an array; got %s.', command, value) : invariant(Array.isArray(value));
|
|
57
48
|
var specValue = spec[command];
|
|
58
|
-
|
|
59
|
-
Array.isArray(specValue),
|
|
60
|
-
'update(): expected spec of %s to be an array; got %s. ' +
|
|
61
|
-
'Did you forget to wrap your parameter in an array?',
|
|
62
|
-
command,
|
|
63
|
-
specValue
|
|
64
|
-
) : invariant(Array.isArray(specValue)));
|
|
49
|
+
'production' !== process.env.NODE_ENV ? invariant(Array.isArray(specValue), 'update(): expected spec of %s to be an array; got %s. ' + 'Did you forget to wrap your parameter in an array?', command, specValue) : invariant(Array.isArray(specValue));
|
|
65
50
|
}
|
|
66
51
|
|
|
67
52
|
function update(value, spec) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
'
|
|
72
|
-
ALL_COMMANDS_LIST.join(', '),
|
|
73
|
-
COMMAND_SET
|
|
74
|
-
) : invariant(typeof spec === 'object'));
|
|
75
|
-
|
|
76
|
-
if (spec.hasOwnProperty(COMMAND_SET)) {
|
|
77
|
-
("production" !== process.env.NODE_ENV ? invariant(
|
|
78
|
-
Object.keys(spec).length === 1,
|
|
79
|
-
'Cannot have more than one key in an object with %s',
|
|
80
|
-
COMMAND_SET
|
|
81
|
-
) : invariant(Object.keys(spec).length === 1));
|
|
53
|
+
'production' !== process.env.NODE_ENV ? invariant(typeof spec === 'object', 'update(): You provided a key path to update() that did not contain one ' + 'of %s. Did you forget to include {%s: ...}?', ALL_COMMANDS_LIST.join(', '), COMMAND_SET) : invariant(typeof spec === 'object');
|
|
54
|
+
|
|
55
|
+
if (hasOwnProperty.call(spec, COMMAND_SET)) {
|
|
56
|
+
'production' !== process.env.NODE_ENV ? invariant(Object.keys(spec).length === 1, 'Cannot have more than one key in an object with %s', COMMAND_SET) : invariant(Object.keys(spec).length === 1);
|
|
82
57
|
|
|
83
58
|
return spec[COMMAND_SET];
|
|
84
59
|
}
|
|
85
60
|
|
|
86
61
|
var nextValue = shallowCopy(value);
|
|
87
62
|
|
|
88
|
-
if (
|
|
63
|
+
if (hasOwnProperty.call(spec, COMMAND_MERGE)) {
|
|
89
64
|
var mergeObj = spec[COMMAND_MERGE];
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
'update(): %s expects a spec of type \'object\'; got %s',
|
|
93
|
-
COMMAND_MERGE,
|
|
94
|
-
mergeObj
|
|
95
|
-
) : invariant(mergeObj && typeof mergeObj === 'object'));
|
|
96
|
-
("production" !== process.env.NODE_ENV ? invariant(
|
|
97
|
-
nextValue && typeof nextValue === 'object',
|
|
98
|
-
'update(): %s expects a target of type \'object\'; got %s',
|
|
99
|
-
COMMAND_MERGE,
|
|
100
|
-
nextValue
|
|
101
|
-
) : invariant(nextValue && typeof nextValue === 'object'));
|
|
65
|
+
'production' !== process.env.NODE_ENV ? invariant(mergeObj && typeof mergeObj === 'object', 'update(): %s expects a spec of type \'object\'; got %s', COMMAND_MERGE, mergeObj) : invariant(mergeObj && typeof mergeObj === 'object');
|
|
66
|
+
'production' !== process.env.NODE_ENV ? invariant(nextValue && typeof nextValue === 'object', 'update(): %s expects a target of type \'object\'; got %s', COMMAND_MERGE, nextValue) : invariant(nextValue && typeof nextValue === 'object');
|
|
102
67
|
assign(nextValue, spec[COMMAND_MERGE]);
|
|
103
68
|
}
|
|
104
69
|
|
|
105
|
-
if (
|
|
70
|
+
if (hasOwnProperty.call(spec, COMMAND_PUSH)) {
|
|
106
71
|
invariantArrayCase(value, spec, COMMAND_PUSH);
|
|
107
|
-
spec[COMMAND_PUSH].forEach(function(item) {
|
|
72
|
+
spec[COMMAND_PUSH].forEach(function (item) {
|
|
108
73
|
nextValue.push(item);
|
|
109
74
|
});
|
|
110
75
|
}
|
|
111
76
|
|
|
112
|
-
if (
|
|
77
|
+
if (hasOwnProperty.call(spec, COMMAND_UNSHIFT)) {
|
|
113
78
|
invariantArrayCase(value, spec, COMMAND_UNSHIFT);
|
|
114
|
-
spec[COMMAND_UNSHIFT].forEach(function(item) {
|
|
79
|
+
spec[COMMAND_UNSHIFT].forEach(function (item) {
|
|
115
80
|
nextValue.unshift(item);
|
|
116
81
|
});
|
|
117
82
|
}
|
|
118
83
|
|
|
119
|
-
if (
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
COMMAND_SPLICE,
|
|
124
|
-
value
|
|
125
|
-
) : invariant(Array.isArray(value)));
|
|
126
|
-
("production" !== process.env.NODE_ENV ? invariant(
|
|
127
|
-
Array.isArray(spec[COMMAND_SPLICE]),
|
|
128
|
-
'update(): expected spec of %s to be an array of arrays; got %s. ' +
|
|
129
|
-
'Did you forget to wrap your parameters in an array?',
|
|
130
|
-
COMMAND_SPLICE,
|
|
131
|
-
spec[COMMAND_SPLICE]
|
|
132
|
-
) : invariant(Array.isArray(spec[COMMAND_SPLICE])));
|
|
133
|
-
spec[COMMAND_SPLICE].forEach(function(args) {
|
|
134
|
-
("production" !== process.env.NODE_ENV ? invariant(
|
|
135
|
-
Array.isArray(args),
|
|
136
|
-
'update(): expected spec of %s to be an array of arrays; got %s. ' +
|
|
137
|
-
'Did you forget to wrap your parameters in an array?',
|
|
138
|
-
COMMAND_SPLICE,
|
|
139
|
-
spec[COMMAND_SPLICE]
|
|
140
|
-
) : invariant(Array.isArray(args)));
|
|
84
|
+
if (hasOwnProperty.call(spec, COMMAND_SPLICE)) {
|
|
85
|
+
'production' !== process.env.NODE_ENV ? invariant(Array.isArray(value), 'Expected %s target to be an array; got %s', COMMAND_SPLICE, value) : invariant(Array.isArray(value));
|
|
86
|
+
'production' !== process.env.NODE_ENV ? invariant(Array.isArray(spec[COMMAND_SPLICE]), 'update(): expected spec of %s to be an array of arrays; got %s. ' + 'Did you forget to wrap your parameters in an array?', COMMAND_SPLICE, spec[COMMAND_SPLICE]) : invariant(Array.isArray(spec[COMMAND_SPLICE]));
|
|
87
|
+
spec[COMMAND_SPLICE].forEach(function (args) {
|
|
88
|
+
'production' !== process.env.NODE_ENV ? invariant(Array.isArray(args), 'update(): expected spec of %s to be an array of arrays; got %s. ' + 'Did you forget to wrap your parameters in an array?', COMMAND_SPLICE, spec[COMMAND_SPLICE]) : invariant(Array.isArray(args));
|
|
141
89
|
nextValue.splice.apply(nextValue, args);
|
|
142
90
|
});
|
|
143
91
|
}
|
|
144
92
|
|
|
145
|
-
if (
|
|
146
|
-
|
|
147
|
-
typeof spec[COMMAND_APPLY] === 'function',
|
|
148
|
-
'update(): expected spec of %s to be a function; got %s.',
|
|
149
|
-
COMMAND_APPLY,
|
|
150
|
-
spec[COMMAND_APPLY]
|
|
151
|
-
) : invariant(typeof spec[COMMAND_APPLY] === 'function'));
|
|
93
|
+
if (hasOwnProperty.call(spec, COMMAND_APPLY)) {
|
|
94
|
+
'production' !== process.env.NODE_ENV ? invariant(typeof spec[COMMAND_APPLY] === 'function', 'update(): expected spec of %s to be a function; got %s.', COMMAND_APPLY, spec[COMMAND_APPLY]) : invariant(typeof spec[COMMAND_APPLY] === 'function');
|
|
152
95
|
nextValue = spec[COMMAND_APPLY](nextValue);
|
|
153
96
|
}
|
|
154
97
|
|
|
@@ -161,4 +104,4 @@ function update(value, spec) {
|
|
|
161
104
|
return nextValue;
|
|
162
105
|
}
|
|
163
106
|
|
|
164
|
-
module.exports = update;
|
|
107
|
+
module.exports = update;
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2015, Facebook, Inc.
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the BSD-style license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree. An additional grant
|
|
7
|
+
* of patent rights can be found in the PATENTS file in the same directory.
|
|
8
|
+
*
|
|
9
|
+
* @providesModule validateDOMNesting
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
'use strict';
|
|
13
|
+
|
|
14
|
+
var emptyFunction = require("./emptyFunction");
|
|
15
|
+
var warning = require("./warning");
|
|
16
|
+
|
|
17
|
+
var validateDOMNesting = emptyFunction;
|
|
18
|
+
|
|
19
|
+
if ('production' !== process.env.NODE_ENV) {
|
|
20
|
+
// This validation code was written based on the HTML5 parsing spec:
|
|
21
|
+
// https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
|
|
22
|
+
//
|
|
23
|
+
// Note: this does not catch all invalid nesting, nor does it try to (as it's
|
|
24
|
+
// not clear what practical benefit doing so provides); instead, we warn only
|
|
25
|
+
// for cases where the parser will give a parse tree differing from what React
|
|
26
|
+
// intended. For example, <b><div></div></b> is invalid but we don't warn
|
|
27
|
+
// because it still parses correctly; we do warn for other cases like nested
|
|
28
|
+
// <p> tags where the beginning of the second element implicitly closes the
|
|
29
|
+
// first, causing a confusing mess.
|
|
30
|
+
|
|
31
|
+
// https://html.spec.whatwg.org/multipage/syntax.html#special
|
|
32
|
+
var specialTags = ['address', 'applet', 'area', 'article', 'aside', 'base', 'basefont', 'bgsound', 'blockquote', 'body', 'br', 'button', 'caption', 'center', 'col', 'colgroup', 'dd', 'details', 'dir', 'div', 'dl', 'dt', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'iframe', 'img', 'input', 'isindex', 'li', 'link', 'listing', 'main', 'marquee', 'menu', 'menuitem', 'meta', 'nav', 'noembed', 'noframes', 'noscript', 'object', 'ol', 'p', 'param', 'plaintext', 'pre', 'script', 'section', 'select', 'source', 'style', 'summary', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'track', 'ul', 'wbr', 'xmp'];
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Return whether `stack` contains `tag` and the last occurrence of `tag` is
|
|
36
|
+
* deeper than any element in the `scope` array.
|
|
37
|
+
*
|
|
38
|
+
* https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-the-specific-scope
|
|
39
|
+
*
|
|
40
|
+
* Examples:
|
|
41
|
+
* stackHasTagInSpecificScope(['p', 'quote'], 'p', ['button']) is true
|
|
42
|
+
* stackHasTagInSpecificScope(['p', 'button'], 'p', ['button']) is false
|
|
43
|
+
*
|
|
44
|
+
* @param {Array<string>} stack
|
|
45
|
+
* @param {string} tag
|
|
46
|
+
* @param {Array<string>} scope
|
|
47
|
+
*/
|
|
48
|
+
var stackHasTagInSpecificScope = function (stack, tag, scope) {
|
|
49
|
+
for (var i = stack.length - 1; i >= 0; i--) {
|
|
50
|
+
if (stack[i] === tag) {
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
if (scope.indexOf(stack[i]) !== -1) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return false;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
|
|
61
|
+
var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template',
|
|
62
|
+
|
|
63
|
+
// https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
|
|
64
|
+
// TODO: Distinguish by namespace here
|
|
65
|
+
'foreignObject', 'desc', 'title'];
|
|
66
|
+
var stackHasTagInScope = function (stack, tag) {
|
|
67
|
+
return stackHasTagInSpecificScope(stack, tag, inScopeTags);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
|
|
71
|
+
var buttonScopeTags = inScopeTags.concat(['button']);
|
|
72
|
+
var stackHasTagInButtonScope = function (stack, tag) {
|
|
73
|
+
return stackHasTagInSpecificScope(stack, tag, buttonScopeTags);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// See rules for 'li', 'dd', 'dt' start tags in
|
|
77
|
+
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
|
|
78
|
+
var listItemTagAllowed = function (tags, stack) {
|
|
79
|
+
// tags is ['li'] or ['dd, 'dt']
|
|
80
|
+
for (var i = stack.length - 1; i >= 0; i--) {
|
|
81
|
+
if (tags.indexOf(stack[i]) !== -1) {
|
|
82
|
+
return false;
|
|
83
|
+
} else if (specialTags.indexOf(stack[i]) !== -1 && stack[i] !== 'address' && stack[i] !== 'div' && stack[i] !== 'p') {
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return true;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
// https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
|
|
91
|
+
var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Returns whether we allow putting `tag` in the document if the current stack
|
|
95
|
+
* of open tags is `openTagStack`.
|
|
96
|
+
*
|
|
97
|
+
* Examples:
|
|
98
|
+
* isTagValidInContext('tr', [..., 'table', 'tbody']) is true
|
|
99
|
+
* isTagValidInContext('tr', [..., 'table']) is false
|
|
100
|
+
*
|
|
101
|
+
* @param {string} tag Lowercase HTML tag name or node name like '#text'
|
|
102
|
+
* @param {Array<string>} openTagStack
|
|
103
|
+
*/
|
|
104
|
+
var isTagValidInContext = function (tag, openTagStack) {
|
|
105
|
+
var currentTag = openTagStack[openTagStack.length - 1];
|
|
106
|
+
|
|
107
|
+
// First, let's check if we're in an unusual parsing mode...
|
|
108
|
+
switch (currentTag) {
|
|
109
|
+
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
|
|
110
|
+
case 'select':
|
|
111
|
+
return tag === 'option' || tag === 'optgroup' || tag === '#text';
|
|
112
|
+
case 'optgroup':
|
|
113
|
+
return tag === 'option' || tag === '#text';
|
|
114
|
+
// Strictly speaking, seeing an <option> doesn't mean we're in a <select>
|
|
115
|
+
// but
|
|
116
|
+
case 'option':
|
|
117
|
+
return tag === '#text';
|
|
118
|
+
|
|
119
|
+
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
|
|
120
|
+
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
|
|
121
|
+
// No special behavior since these rules fall back to "in body" mode for
|
|
122
|
+
// all except special table nodes which cause bad parsing behavior anyway.
|
|
123
|
+
|
|
124
|
+
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
|
|
125
|
+
case 'tr':
|
|
126
|
+
return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';
|
|
127
|
+
|
|
128
|
+
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
|
|
129
|
+
case 'tbody':
|
|
130
|
+
case 'thead':
|
|
131
|
+
case 'tfoot':
|
|
132
|
+
return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';
|
|
133
|
+
|
|
134
|
+
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
|
|
135
|
+
case 'colgroup':
|
|
136
|
+
return tag === 'col' || tag === 'template';
|
|
137
|
+
|
|
138
|
+
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
|
|
139
|
+
case 'table':
|
|
140
|
+
return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';
|
|
141
|
+
|
|
142
|
+
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
|
|
143
|
+
case 'head':
|
|
144
|
+
return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';
|
|
145
|
+
|
|
146
|
+
// https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
|
|
147
|
+
case 'html':
|
|
148
|
+
return tag === 'head' || tag === 'body';
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Probably in the "in body" parsing mode, so we outlaw only tag combos
|
|
152
|
+
// where the parsing rules cause implicit opens or closes to be added.
|
|
153
|
+
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
|
|
154
|
+
switch (tag) {
|
|
155
|
+
case 'address':
|
|
156
|
+
case 'article':
|
|
157
|
+
case 'aside':
|
|
158
|
+
case 'blockquote':
|
|
159
|
+
case 'center':
|
|
160
|
+
case 'details':
|
|
161
|
+
case 'dialog':
|
|
162
|
+
case 'dir':
|
|
163
|
+
case 'div':
|
|
164
|
+
case 'dl':
|
|
165
|
+
case 'fieldset':
|
|
166
|
+
case 'figcaption':
|
|
167
|
+
case 'figure':
|
|
168
|
+
case 'footer':
|
|
169
|
+
case 'header':
|
|
170
|
+
case 'hgroup':
|
|
171
|
+
case 'main':
|
|
172
|
+
case 'menu':
|
|
173
|
+
case 'nav':
|
|
174
|
+
case 'ol':
|
|
175
|
+
case 'p':
|
|
176
|
+
case 'section':
|
|
177
|
+
case 'summary':
|
|
178
|
+
case 'ul':
|
|
179
|
+
|
|
180
|
+
case 'pre':
|
|
181
|
+
case 'listing':
|
|
182
|
+
|
|
183
|
+
case 'table':
|
|
184
|
+
|
|
185
|
+
case 'hr':
|
|
186
|
+
|
|
187
|
+
case 'xmp':
|
|
188
|
+
return !stackHasTagInButtonScope(openTagStack, 'p');
|
|
189
|
+
|
|
190
|
+
case 'h1':
|
|
191
|
+
case 'h2':
|
|
192
|
+
case 'h3':
|
|
193
|
+
case 'h4':
|
|
194
|
+
case 'h5':
|
|
195
|
+
case 'h6':
|
|
196
|
+
return !stackHasTagInButtonScope(openTagStack, 'p') && currentTag !== 'h1' && currentTag !== 'h2' && currentTag !== 'h3' && currentTag !== 'h4' && currentTag !== 'h5' && currentTag !== 'h6';
|
|
197
|
+
|
|
198
|
+
case 'form':
|
|
199
|
+
return openTagStack.indexOf('form') === -1 && !stackHasTagInButtonScope(openTagStack, 'p');
|
|
200
|
+
|
|
201
|
+
case 'li':
|
|
202
|
+
return listItemTagAllowed(['li'], openTagStack);
|
|
203
|
+
|
|
204
|
+
case 'dd':
|
|
205
|
+
case 'dt':
|
|
206
|
+
return listItemTagAllowed(['dd', 'dt'], openTagStack);
|
|
207
|
+
|
|
208
|
+
case 'button':
|
|
209
|
+
return !stackHasTagInScope(openTagStack, 'button');
|
|
210
|
+
|
|
211
|
+
case 'a':
|
|
212
|
+
// Spec says something about storing a list of markers, but it sounds
|
|
213
|
+
// equivalent to this check.
|
|
214
|
+
return !stackHasTagInScope(openTagStack, 'a');
|
|
215
|
+
|
|
216
|
+
case 'nobr':
|
|
217
|
+
return !stackHasTagInScope(openTagStack, 'nobr');
|
|
218
|
+
|
|
219
|
+
case 'rp':
|
|
220
|
+
case 'rt':
|
|
221
|
+
return impliedEndTags.indexOf(currentTag) === -1;
|
|
222
|
+
|
|
223
|
+
case 'caption':
|
|
224
|
+
case 'col':
|
|
225
|
+
case 'colgroup':
|
|
226
|
+
case 'frame':
|
|
227
|
+
case 'head':
|
|
228
|
+
case 'tbody':
|
|
229
|
+
case 'td':
|
|
230
|
+
case 'tfoot':
|
|
231
|
+
case 'th':
|
|
232
|
+
case 'thead':
|
|
233
|
+
case 'tr':
|
|
234
|
+
return currentTag === undefined;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return true;
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
validateDOMNesting = function (parentStack, childTag, element) {
|
|
241
|
+
if (!isTagValidInContext(childTag, parentStack)) {
|
|
242
|
+
var info = '';
|
|
243
|
+
var parentTag = parentStack[parentStack.length - 1];
|
|
244
|
+
if (parentTag === 'table' && childTag === 'tr') {
|
|
245
|
+
info += ' Add a <tbody> to your code to match the DOM tree generated by ' + 'the browser.';
|
|
246
|
+
}
|
|
247
|
+
if (element && element._owner) {
|
|
248
|
+
var name = element._owner.getName();
|
|
249
|
+
if (name) {
|
|
250
|
+
info += ' Check the render method of `' + name + '`.';
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
'production' !== process.env.NODE_ENV ? warning(false, 'validateDOMNesting(...): <%s> cannot appear as a child of <%s> ' + 'in this context (%s).%s', childTag, parentTag, parentStack.join(' > '), info) : null;
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
validateDOMNesting.tagStackContextKey = '__validateDOMNesting_tagStack$' + Math.random().toString(36).slice(2);
|
|
259
|
+
|
|
260
|
+
// For testing
|
|
261
|
+
validateDOMNesting.isTagValidInContext = isTagValidInContext;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
module.exports = validateDOMNesting;
|
package/lib/warning.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* @providesModule warning
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
'use strict';
|
|
13
13
|
|
|
14
14
|
var emptyFunction = require("./emptyFunction");
|
|
15
15
|
|
|
@@ -22,20 +22,18 @@ var emptyFunction = require("./emptyFunction");
|
|
|
22
22
|
|
|
23
23
|
var warning = emptyFunction;
|
|
24
24
|
|
|
25
|
-
if (
|
|
26
|
-
warning = function(condition, format
|
|
25
|
+
if ('production' !== process.env.NODE_ENV) {
|
|
26
|
+
warning = function (condition, format) {
|
|
27
|
+
for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
|
|
28
|
+
args[_key - 2] = arguments[_key];
|
|
29
|
+
}
|
|
30
|
+
|
|
27
31
|
if (format === undefined) {
|
|
28
|
-
throw new Error(
|
|
29
|
-
'`warning(condition, format, ...args)` requires a warning ' +
|
|
30
|
-
'message argument'
|
|
31
|
-
);
|
|
32
|
+
throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument');
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
if (format.length < 10 || /^[s\W]*$/.test(format)) {
|
|
35
|
-
throw new Error(
|
|
36
|
-
'The warning format should be able to uniquely identify this ' +
|
|
37
|
-
'warning. Please, use a more descriptive format than: ' + format
|
|
38
|
-
);
|
|
36
|
+
throw new Error('The warning format should be able to uniquely identify this ' + 'warning. Please, use a more descriptive format than: ' + format);
|
|
39
37
|
}
|
|
40
38
|
|
|
41
39
|
if (format.indexOf('Failed Composite propType: ') === 0) {
|
|
@@ -44,16 +42,20 @@ if ("production" !== process.env.NODE_ENV) {
|
|
|
44
42
|
|
|
45
43
|
if (!condition) {
|
|
46
44
|
var argIndex = 0;
|
|
47
|
-
var message = 'Warning: ' + format.replace(/%s/g, function()
|
|
48
|
-
|
|
45
|
+
var message = 'Warning: ' + format.replace(/%s/g, function () {
|
|
46
|
+
return args[argIndex++];
|
|
47
|
+
});
|
|
48
|
+
if (typeof console !== 'undefined') {
|
|
49
|
+
console.error(message);
|
|
50
|
+
}
|
|
49
51
|
try {
|
|
50
52
|
// --- Welcome to debugging React ---
|
|
51
53
|
// This error was thrown as a convenience so that you can use this stack
|
|
52
54
|
// to find the callsite that caused this warning to fire.
|
|
53
55
|
throw new Error(message);
|
|
54
|
-
} catch(x) {}
|
|
56
|
+
} catch (x) {}
|
|
55
57
|
}
|
|
56
58
|
};
|
|
57
59
|
}
|
|
58
60
|
|
|
59
|
-
module.exports = warning;
|
|
61
|
+
module.exports = warning;
|