react 15.3.1-rc.2 → 15.4.0-rc.1

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.
Files changed (190) hide show
  1. package/dist/react-with-addons.js +3961 -21387
  2. package/dist/react-with-addons.min.js +3 -6
  3. package/dist/react.js +2701 -19464
  4. package/dist/react.min.js +2 -6
  5. package/lib/LinkedStateMixin.js +1 -2
  6. package/lib/PooledClass.js +3 -0
  7. package/lib/ReactAddonsDOMDependencies.js +36 -0
  8. package/lib/ReactAddonsDOMDependenciesUMDShim.js +32 -0
  9. package/lib/ReactCSSTransitionGroup.js +60 -42
  10. package/lib/ReactCSSTransitionGroupChild.js +2 -2
  11. package/lib/ReactClass.js +38 -53
  12. package/lib/ReactComponentTreeHook.js +84 -100
  13. package/lib/{DOMNamespaces.js → ReactComponentTreeHookUMDShim.js} +5 -7
  14. package/lib/ReactCurrentOwner.js +1 -1
  15. package/lib/{renderSubtreeIntoContainer.js → ReactCurrentOwnerUMDShim.js} +6 -4
  16. package/lib/ReactElement.js +6 -29
  17. package/lib/ReactElementSymbol.js +20 -0
  18. package/lib/{ReactDOMComponentFlags.js → ReactElementType.js} +4 -9
  19. package/lib/ReactElementValidator.js +1 -2
  20. package/lib/ReactPropTypeLocationNames.js +1 -0
  21. package/lib/ReactPropTypeLocations.js +2 -11
  22. package/lib/ReactPropTypes.js +30 -13
  23. package/lib/ReactPropTypesSecret.js +1 -0
  24. package/lib/ReactTransitionEvents.js +1 -1
  25. package/lib/ReactTransitionGroup.js +145 -141
  26. package/lib/ReactUMDEntry.js +11 -5
  27. package/lib/{ReactDOMFeatureFlags.js → ReactUMDShim.js} +4 -6
  28. package/lib/ReactVersion.js +1 -1
  29. package/lib/ReactWithAddons.js +15 -2
  30. package/lib/ReactWithAddonsUMDEntry.js +11 -5
  31. package/lib/canDefineProperty.js +2 -0
  32. package/lib/onlyChild.js +1 -1
  33. package/lib/traverseAllChildren.js +11 -2
  34. package/lib/update.js +6 -7
  35. package/package.json +2 -2
  36. package/lib/AutoFocusUtils.js +0 -24
  37. package/lib/BeforeInputEventPlugin.js +0 -388
  38. package/lib/CSSProperty.js +0 -148
  39. package/lib/CSSPropertyOperations.js +0 -205
  40. package/lib/CallbackQueue.js +0 -106
  41. package/lib/ChangeEventPlugin.js +0 -325
  42. package/lib/DOMChildrenOperations.js +0 -194
  43. package/lib/DOMLazyTree.js +0 -118
  44. package/lib/DOMProperty.js +0 -206
  45. package/lib/DOMPropertyOperations.js +0 -221
  46. package/lib/Danger.js +0 -48
  47. package/lib/DefaultEventPluginOrder.js +0 -27
  48. package/lib/DisabledInputUtils.js +0 -50
  49. package/lib/EnterLeaveEventPlugin.js +0 -105
  50. package/lib/EventConstants.js +0 -97
  51. package/lib/EventPluginHub.js +0 -251
  52. package/lib/EventPluginRegistry.js +0 -247
  53. package/lib/EventPluginUtils.js +0 -229
  54. package/lib/EventPropagators.js +0 -137
  55. package/lib/FallbackCompositionState.js +0 -95
  56. package/lib/HTMLDOMPropertyConfig.js +0 -209
  57. package/lib/LinkedValueUtils.js +0 -136
  58. package/lib/NativeMethodsMixin.js +0 -167
  59. package/lib/ReactBrowserEventEmitter.js +0 -317
  60. package/lib/ReactChildReconciler.js +0 -154
  61. package/lib/ReactChildrenMutationWarningHook.js +0 -54
  62. package/lib/ReactComponentBrowserEnvironment.js +0 -30
  63. package/lib/ReactComponentEnvironment.js +0 -45
  64. package/lib/ReactComponentTreeTestUtils.js +0 -87
  65. package/lib/ReactCompositeComponent.js +0 -920
  66. package/lib/ReactDOM.js +0 -110
  67. package/lib/ReactDOMButton.js +0 -24
  68. package/lib/ReactDOMComponent.js +0 -1005
  69. package/lib/ReactDOMComponentTree.js +0 -188
  70. package/lib/ReactDOMContainerInfo.js +0 -33
  71. package/lib/ReactDOMEmptyComponent.js +0 -60
  72. package/lib/ReactDOMFiber.js +0 -78
  73. package/lib/ReactDOMIDOperations.js +0 -34
  74. package/lib/ReactDOMInput.js +0 -269
  75. package/lib/ReactDOMNullInputValuePropHook.js +0 -43
  76. package/lib/ReactDOMOption.js +0 -123
  77. package/lib/ReactDOMSelect.js +0 -201
  78. package/lib/ReactDOMSelection.js +0 -212
  79. package/lib/ReactDOMServer.js +0 -26
  80. package/lib/ReactDOMTextComponent.js +0 -164
  81. package/lib/ReactDOMTextarea.js +0 -155
  82. package/lib/ReactDOMTreeTraversal.js +0 -136
  83. package/lib/ReactDOMUnknownPropertyHook.js +0 -112
  84. package/lib/ReactDebugTool.js +0 -307
  85. package/lib/ReactDefaultBatchingStrategy.js +0 -68
  86. package/lib/ReactDefaultInjection.js +0 -84
  87. package/lib/ReactEmptyComponent.js +0 -30
  88. package/lib/ReactErrorUtils.js +0 -76
  89. package/lib/ReactEventEmitterMixin.js +0 -33
  90. package/lib/ReactEventListener.js +0 -157
  91. package/lib/ReactFeatureFlags.js +0 -22
  92. package/lib/ReactHostComponent.js +0 -76
  93. package/lib/ReactHostOperationHistoryHook.js +0 -37
  94. package/lib/ReactInjection.js +0 -36
  95. package/lib/ReactInputSelection.js +0 -124
  96. package/lib/ReactInstanceHandles.js +0 -302
  97. package/lib/ReactInstanceMap.js +0 -48
  98. package/lib/ReactInstrumentation.js +0 -21
  99. package/lib/ReactInvalidSetStateWarningHook.js +0 -36
  100. package/lib/ReactMarkupChecksum.js +0 -50
  101. package/lib/ReactMount.js +0 -495
  102. package/lib/ReactMultiChild.js +0 -451
  103. package/lib/ReactMultiChildUpdateTypes.js +0 -32
  104. package/lib/ReactNative.js +0 -71
  105. package/lib/ReactNativeAttributePayload.js +0 -371
  106. package/lib/ReactNativeBaseComponent.js +0 -198
  107. package/lib/ReactNativeBridgeEventPlugin.js +0 -60
  108. package/lib/ReactNativeComponentEnvironment.js +0 -31
  109. package/lib/ReactNativeComponentTree.js +0 -68
  110. package/lib/ReactNativeContainerInfo.js +0 -21
  111. package/lib/ReactNativeDOMIDOperations.js +0 -79
  112. package/lib/ReactNativeDefaultInjection.js +0 -101
  113. package/lib/ReactNativeEventEmitter.js +0 -191
  114. package/lib/ReactNativeEventPluginOrder.js +0 -16
  115. package/lib/ReactNativeGlobalResponderHandler.js +0 -25
  116. package/lib/ReactNativeMount.js +0 -193
  117. package/lib/ReactNativePropRegistry.js +0 -52
  118. package/lib/ReactNativeReconcileTransaction.js +0 -116
  119. package/lib/ReactNativeTagHandles.js +0 -56
  120. package/lib/ReactNativeTextComponent.js +0 -71
  121. package/lib/ReactNativeTreeTraversal.js +0 -127
  122. package/lib/ReactNodeTypes.js +0 -40
  123. package/lib/ReactNoop.js +0 -173
  124. package/lib/ReactOwner.js +0 -94
  125. package/lib/ReactPerf.js +0 -494
  126. package/lib/ReactReconcileTransaction.js +0 -178
  127. package/lib/ReactReconciler.js +0 -168
  128. package/lib/ReactRef.js +0 -80
  129. package/lib/ReactServerBatchingStrategy.js +0 -22
  130. package/lib/ReactServerRendering.js +0 -90
  131. package/lib/ReactServerRenderingTransaction.js +0 -90
  132. package/lib/ReactServerUpdateQueue.js +0 -141
  133. package/lib/ReactSimpleEmptyComponent.js +0 -37
  134. package/lib/ReactTestMount.js +0 -123
  135. package/lib/ReactTestReconcileTransaction.js +0 -108
  136. package/lib/ReactTestRenderer.js +0 -144
  137. package/lib/ReactTestUtils.js +0 -518
  138. package/lib/ReactUpdateQueue.js +0 -226
  139. package/lib/ReactUpdates.js +0 -251
  140. package/lib/ResponderEventPlugin.js +0 -510
  141. package/lib/ResponderSyntheticEvent.js +0 -39
  142. package/lib/ResponderTouchHistoryStore.js +0 -184
  143. package/lib/SVGDOMPropertyConfig.js +0 -302
  144. package/lib/SelectEventPlugin.js +0 -196
  145. package/lib/SimpleEventPlugin.js +0 -635
  146. package/lib/SyntheticAnimationEvent.js +0 -39
  147. package/lib/SyntheticClipboardEvent.js +0 -38
  148. package/lib/SyntheticCompositionEvent.js +0 -36
  149. package/lib/SyntheticDragEvent.js +0 -36
  150. package/lib/SyntheticEvent.js +0 -267
  151. package/lib/SyntheticFocusEvent.js +0 -36
  152. package/lib/SyntheticInputEvent.js +0 -37
  153. package/lib/SyntheticKeyboardEvent.js +0 -84
  154. package/lib/SyntheticMouseEvent.js +0 -72
  155. package/lib/SyntheticTouchEvent.js +0 -45
  156. package/lib/SyntheticTransitionEvent.js +0 -39
  157. package/lib/SyntheticUIEvent.js +0 -59
  158. package/lib/SyntheticWheelEvent.js +0 -54
  159. package/lib/TapEventPlugin.js +0 -110
  160. package/lib/TouchHistoryMath.js +0 -99
  161. package/lib/Transaction.js +0 -233
  162. package/lib/ViewportMetrics.js +0 -27
  163. package/lib/accumulate.js +0 -46
  164. package/lib/accumulateInto.js +0 -58
  165. package/lib/adler32.js +0 -44
  166. package/lib/createMicrosoftUnsafeLocalFunction.js +0 -32
  167. package/lib/createReactNativeComponentClass.js +0 -42
  168. package/lib/dangerousStyleValue.js +0 -79
  169. package/lib/escapeTextContentForBrowser.js +0 -122
  170. package/lib/findDOMNode.js +0 -60
  171. package/lib/findNodeHandle.js +0 -91
  172. package/lib/forEachAccumulated.js +0 -31
  173. package/lib/getEventCharCode.js +0 -50
  174. package/lib/getEventKey.js +0 -102
  175. package/lib/getEventModifierState.js +0 -43
  176. package/lib/getEventTarget.js +0 -35
  177. package/lib/getHostComponentFromComposite.js +0 -30
  178. package/lib/getNodeForCharacterOffset.js +0 -74
  179. package/lib/getTestDocument.js +0 -21
  180. package/lib/getTextContentAccessor.js +0 -33
  181. package/lib/getVendorPrefixedEventName.js +0 -101
  182. package/lib/instantiateReactComponent.js +0 -119
  183. package/lib/isEventSupported.js +0 -60
  184. package/lib/isTextInputElement.js +0 -51
  185. package/lib/quoteAttributeValueForBrowser.js +0 -26
  186. package/lib/reactComponentExpect.js +0 -217
  187. package/lib/setInnerHTML.js +0 -98
  188. package/lib/setTextContent.js +0 -48
  189. package/lib/shouldUpdateReactComponent.js +0 -42
  190. package/lib/validateDOMNesting.js +0 -369
@@ -1,98 +0,0 @@
1
- /**
2
- * Copyright 2013-present, 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 setInnerHTML
10
- */
11
-
12
- 'use strict';
13
-
14
- var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');
15
- var DOMNamespaces = require('./DOMNamespaces');
16
-
17
- var WHITESPACE_TEST = /^[ \r\n\t\f]/;
18
- var NONVISIBLE_TEST = /<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/;
19
-
20
- var createMicrosoftUnsafeLocalFunction = require('./createMicrosoftUnsafeLocalFunction');
21
-
22
- // SVG temp container for IE lacking innerHTML
23
- var reusableSVGContainer;
24
-
25
- /**
26
- * Set the innerHTML property of a node, ensuring that whitespace is preserved
27
- * even in IE8.
28
- *
29
- * @param {DOMElement} node
30
- * @param {string} html
31
- * @internal
32
- */
33
- var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) {
34
- // IE does not have innerHTML for SVG nodes, so instead we inject the
35
- // new markup in a temp node and then move the child nodes across into
36
- // the target node
37
- if (node.namespaceURI === DOMNamespaces.svg && !('innerHTML' in node)) {
38
- reusableSVGContainer = reusableSVGContainer || document.createElement('div');
39
- reusableSVGContainer.innerHTML = '<svg>' + html + '</svg>';
40
- var newNodes = reusableSVGContainer.firstChild.childNodes;
41
- for (var i = 0; i < newNodes.length; i++) {
42
- node.appendChild(newNodes[i]);
43
- }
44
- } else {
45
- node.innerHTML = html;
46
- }
47
- });
48
-
49
- if (ExecutionEnvironment.canUseDOM) {
50
- // IE8: When updating a just created node with innerHTML only leading
51
- // whitespace is removed. When updating an existing node with innerHTML
52
- // whitespace in root TextNodes is also collapsed.
53
- // @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html
54
-
55
- // Feature detection; only IE8 is known to behave improperly like this.
56
- var testElement = document.createElement('div');
57
- testElement.innerHTML = ' ';
58
- if (testElement.innerHTML === '') {
59
- setInnerHTML = function (node, html) {
60
- // Magic theory: IE8 supposedly differentiates between added and updated
61
- // nodes when processing innerHTML, innerHTML on updated nodes suffers
62
- // from worse whitespace behavior. Re-adding a node like this triggers
63
- // the initial and more favorable whitespace behavior.
64
- // TODO: What to do on a detached node?
65
- if (node.parentNode) {
66
- node.parentNode.replaceChild(node, node);
67
- }
68
-
69
- // We also implement a workaround for non-visible tags disappearing into
70
- // thin air on IE8, this only happens if there is no visible text
71
- // in-front of the non-visible tags. Piggyback on the whitespace fix
72
- // and simply check if any non-visible tags appear in the source.
73
- if (WHITESPACE_TEST.test(html) || html[0] === '<' && NONVISIBLE_TEST.test(html)) {
74
- // Recover leading whitespace by temporarily prepending any character.
75
- // \uFEFF has the potential advantage of being zero-width/invisible.
76
- // UglifyJS drops U+FEFF chars when parsing, so use String.fromCharCode
77
- // in hopes that this is preserved even if "\uFEFF" is transformed to
78
- // the actual Unicode character (by Babel, for example).
79
- // https://github.com/mishoo/UglifyJS2/blob/v2.4.20/lib/parse.js#L216
80
- node.innerHTML = String.fromCharCode(0xFEFF) + html;
81
-
82
- // deleteData leaves an empty `TextNode` which offsets the index of all
83
- // children. Definitely want to avoid this.
84
- var textNode = node.firstChild;
85
- if (textNode.data.length === 1) {
86
- node.removeChild(textNode);
87
- } else {
88
- textNode.deleteData(0, 1);
89
- }
90
- } else {
91
- node.innerHTML = html;
92
- }
93
- };
94
- }
95
- testElement = null;
96
- }
97
-
98
- module.exports = setInnerHTML;
@@ -1,48 +0,0 @@
1
- /**
2
- * Copyright 2013-present, 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 setTextContent
10
- */
11
-
12
- 'use strict';
13
-
14
- var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');
15
- var escapeTextContentForBrowser = require('./escapeTextContentForBrowser');
16
- var setInnerHTML = require('./setInnerHTML');
17
-
18
- /**
19
- * Set the textContent property of a node, ensuring that whitespace is preserved
20
- * even in IE8. innerText is a poor substitute for textContent and, among many
21
- * issues, inserts <br> instead of the literal newline chars. innerHTML behaves
22
- * as it should.
23
- *
24
- * @param {DOMElement} node
25
- * @param {string} text
26
- * @internal
27
- */
28
- var setTextContent = function (node, text) {
29
- if (text) {
30
- var firstChild = node.firstChild;
31
-
32
- if (firstChild && firstChild === node.lastChild && firstChild.nodeType === 3) {
33
- firstChild.nodeValue = text;
34
- return;
35
- }
36
- }
37
- node.textContent = text;
38
- };
39
-
40
- if (ExecutionEnvironment.canUseDOM) {
41
- if (!('textContent' in document.documentElement)) {
42
- setTextContent = function (node, text) {
43
- setInnerHTML(node, escapeTextContentForBrowser(text));
44
- };
45
- }
46
- }
47
-
48
- module.exports = setTextContent;
@@ -1,42 +0,0 @@
1
- /**
2
- * Copyright 2013-present, 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 shouldUpdateReactComponent
10
- */
11
-
12
- 'use strict';
13
-
14
- /**
15
- * Given a `prevElement` and `nextElement`, determines if the existing
16
- * instance should be updated as opposed to being destroyed or replaced by a new
17
- * instance. Both arguments are elements. This ensures that this logic can
18
- * operate on stateless trees without any backing instance.
19
- *
20
- * @param {?object} prevElement
21
- * @param {?object} nextElement
22
- * @return {boolean} True if the existing instance should be updated.
23
- * @protected
24
- */
25
-
26
- function shouldUpdateReactComponent(prevElement, nextElement) {
27
- var prevEmpty = prevElement === null || prevElement === false;
28
- var nextEmpty = nextElement === null || nextElement === false;
29
- if (prevEmpty || nextEmpty) {
30
- return prevEmpty === nextEmpty;
31
- }
32
-
33
- var prevType = typeof prevElement;
34
- var nextType = typeof nextElement;
35
- if (prevType === 'string' || prevType === 'number') {
36
- return nextType === 'string' || nextType === 'number';
37
- } else {
38
- return nextType === 'object' && prevElement.type === nextElement.type && prevElement.key === nextElement.key;
39
- }
40
- }
41
-
42
- module.exports = shouldUpdateReactComponent;
@@ -1,369 +0,0 @@
1
- /**
2
- * Copyright 2015-present, 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 _assign = require('object-assign');
15
-
16
- var emptyFunction = require('fbjs/lib/emptyFunction');
17
- var warning = require('fbjs/lib/warning');
18
-
19
- var validateDOMNesting = emptyFunction;
20
-
21
- if (process.env.NODE_ENV !== 'production') {
22
- // This validation code was written based on the HTML5 parsing spec:
23
- // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
24
- //
25
- // Note: this does not catch all invalid nesting, nor does it try to (as it's
26
- // not clear what practical benefit doing so provides); instead, we warn only
27
- // for cases where the parser will give a parse tree differing from what React
28
- // intended. For example, <b><div></div></b> is invalid but we don't warn
29
- // because it still parses correctly; we do warn for other cases like nested
30
- // <p> tags where the beginning of the second element implicitly closes the
31
- // first, causing a confusing mess.
32
-
33
- // https://html.spec.whatwg.org/multipage/syntax.html#special
34
- 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'];
35
-
36
- // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
37
- var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template',
38
-
39
- // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
40
- // TODO: Distinguish by namespace here -- for <title>, including it here
41
- // errs on the side of fewer warnings
42
- 'foreignObject', 'desc', 'title'];
43
-
44
- // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
45
- var buttonScopeTags = inScopeTags.concat(['button']);
46
-
47
- // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
48
- var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];
49
-
50
- var emptyAncestorInfo = {
51
- current: null,
52
-
53
- formTag: null,
54
- aTagInScope: null,
55
- buttonTagInScope: null,
56
- nobrTagInScope: null,
57
- pTagInButtonScope: null,
58
-
59
- listItemTagAutoclosing: null,
60
- dlItemTagAutoclosing: null
61
- };
62
-
63
- var updatedAncestorInfo = function (oldInfo, tag, instance) {
64
- var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo);
65
- var info = { tag: tag, instance: instance };
66
-
67
- if (inScopeTags.indexOf(tag) !== -1) {
68
- ancestorInfo.aTagInScope = null;
69
- ancestorInfo.buttonTagInScope = null;
70
- ancestorInfo.nobrTagInScope = null;
71
- }
72
- if (buttonScopeTags.indexOf(tag) !== -1) {
73
- ancestorInfo.pTagInButtonScope = null;
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
- if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {
79
- ancestorInfo.listItemTagAutoclosing = null;
80
- ancestorInfo.dlItemTagAutoclosing = null;
81
- }
82
-
83
- ancestorInfo.current = info;
84
-
85
- if (tag === 'form') {
86
- ancestorInfo.formTag = info;
87
- }
88
- if (tag === 'a') {
89
- ancestorInfo.aTagInScope = info;
90
- }
91
- if (tag === 'button') {
92
- ancestorInfo.buttonTagInScope = info;
93
- }
94
- if (tag === 'nobr') {
95
- ancestorInfo.nobrTagInScope = info;
96
- }
97
- if (tag === 'p') {
98
- ancestorInfo.pTagInButtonScope = info;
99
- }
100
- if (tag === 'li') {
101
- ancestorInfo.listItemTagAutoclosing = info;
102
- }
103
- if (tag === 'dd' || tag === 'dt') {
104
- ancestorInfo.dlItemTagAutoclosing = info;
105
- }
106
-
107
- return ancestorInfo;
108
- };
109
-
110
- /**
111
- * Returns whether
112
- */
113
- var isTagValidWithParent = function (tag, parentTag) {
114
- // First, let's check if we're in an unusual parsing mode...
115
- switch (parentTag) {
116
- // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
117
- case 'select':
118
- return tag === 'option' || tag === 'optgroup' || tag === '#text';
119
- case 'optgroup':
120
- return tag === 'option' || tag === '#text';
121
- // Strictly speaking, seeing an <option> doesn't mean we're in a <select>
122
- // but
123
- case 'option':
124
- return tag === '#text';
125
-
126
- // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
127
- // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
128
- // No special behavior since these rules fall back to "in body" mode for
129
- // all except special table nodes which cause bad parsing behavior anyway.
130
-
131
- // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
132
- case 'tr':
133
- return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';
134
-
135
- // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
136
- case 'tbody':
137
- case 'thead':
138
- case 'tfoot':
139
- return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';
140
-
141
- // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
142
- case 'colgroup':
143
- return tag === 'col' || tag === 'template';
144
-
145
- // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
146
- case 'table':
147
- return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';
148
-
149
- // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
150
- case 'head':
151
- return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';
152
-
153
- // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
154
- case 'html':
155
- return tag === 'head' || tag === 'body';
156
- case '#document':
157
- return tag === 'html';
158
- }
159
-
160
- // Probably in the "in body" parsing mode, so we outlaw only tag combos
161
- // where the parsing rules cause implicit opens or closes to be added.
162
- // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
163
- switch (tag) {
164
- case 'h1':
165
- case 'h2':
166
- case 'h3':
167
- case 'h4':
168
- case 'h5':
169
- case 'h6':
170
- return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';
171
-
172
- case 'rp':
173
- case 'rt':
174
- return impliedEndTags.indexOf(parentTag) === -1;
175
-
176
- case 'body':
177
- case 'caption':
178
- case 'col':
179
- case 'colgroup':
180
- case 'frame':
181
- case 'head':
182
- case 'html':
183
- case 'tbody':
184
- case 'td':
185
- case 'tfoot':
186
- case 'th':
187
- case 'thead':
188
- case 'tr':
189
- // These tags are only valid with a few parents that have special child
190
- // parsing rules -- if we're down here, then none of those matched and
191
- // so we allow it only if we don't know what the parent is, as all other
192
- // cases are invalid.
193
- return parentTag == null;
194
- }
195
-
196
- return true;
197
- };
198
-
199
- /**
200
- * Returns whether
201
- */
202
- var findInvalidAncestorForTag = function (tag, ancestorInfo) {
203
- switch (tag) {
204
- case 'address':
205
- case 'article':
206
- case 'aside':
207
- case 'blockquote':
208
- case 'center':
209
- case 'details':
210
- case 'dialog':
211
- case 'dir':
212
- case 'div':
213
- case 'dl':
214
- case 'fieldset':
215
- case 'figcaption':
216
- case 'figure':
217
- case 'footer':
218
- case 'header':
219
- case 'hgroup':
220
- case 'main':
221
- case 'menu':
222
- case 'nav':
223
- case 'ol':
224
- case 'p':
225
- case 'section':
226
- case 'summary':
227
- case 'ul':
228
-
229
- case 'pre':
230
- case 'listing':
231
-
232
- case 'table':
233
-
234
- case 'hr':
235
-
236
- case 'xmp':
237
-
238
- case 'h1':
239
- case 'h2':
240
- case 'h3':
241
- case 'h4':
242
- case 'h5':
243
- case 'h6':
244
- return ancestorInfo.pTagInButtonScope;
245
-
246
- case 'form':
247
- return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
248
-
249
- case 'li':
250
- return ancestorInfo.listItemTagAutoclosing;
251
-
252
- case 'dd':
253
- case 'dt':
254
- return ancestorInfo.dlItemTagAutoclosing;
255
-
256
- case 'button':
257
- return ancestorInfo.buttonTagInScope;
258
-
259
- case 'a':
260
- // Spec says something about storing a list of markers, but it sounds
261
- // equivalent to this check.
262
- return ancestorInfo.aTagInScope;
263
-
264
- case 'nobr':
265
- return ancestorInfo.nobrTagInScope;
266
- }
267
-
268
- return null;
269
- };
270
-
271
- /**
272
- * Given a ReactCompositeComponent instance, return a list of its recursive
273
- * owners, starting at the root and ending with the instance itself.
274
- */
275
- var findOwnerStack = function (instance) {
276
- if (!instance) {
277
- return [];
278
- }
279
-
280
- var stack = [];
281
- do {
282
- stack.push(instance);
283
- } while (instance = instance._currentElement._owner);
284
- stack.reverse();
285
- return stack;
286
- };
287
-
288
- var didWarn = {};
289
-
290
- validateDOMNesting = function (childTag, childInstance, ancestorInfo) {
291
- ancestorInfo = ancestorInfo || emptyAncestorInfo;
292
- var parentInfo = ancestorInfo.current;
293
- var parentTag = parentInfo && parentInfo.tag;
294
-
295
- var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
296
- var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
297
- var problematic = invalidParent || invalidAncestor;
298
-
299
- if (problematic) {
300
- var ancestorTag = problematic.tag;
301
- var ancestorInstance = problematic.instance;
302
-
303
- var childOwner = childInstance && childInstance._currentElement._owner;
304
- var ancestorOwner = ancestorInstance && ancestorInstance._currentElement._owner;
305
-
306
- var childOwners = findOwnerStack(childOwner);
307
- var ancestorOwners = findOwnerStack(ancestorOwner);
308
-
309
- var minStackLen = Math.min(childOwners.length, ancestorOwners.length);
310
- var i;
311
-
312
- var deepestCommon = -1;
313
- for (i = 0; i < minStackLen; i++) {
314
- if (childOwners[i] === ancestorOwners[i]) {
315
- deepestCommon = i;
316
- } else {
317
- break;
318
- }
319
- }
320
-
321
- var UNKNOWN = '(unknown)';
322
- var childOwnerNames = childOwners.slice(deepestCommon + 1).map(function (inst) {
323
- return inst.getName() || UNKNOWN;
324
- });
325
- var ancestorOwnerNames = ancestorOwners.slice(deepestCommon + 1).map(function (inst) {
326
- return inst.getName() || UNKNOWN;
327
- });
328
- var ownerInfo = [].concat(
329
- // If the parent and child instances have a common owner ancestor, start
330
- // with that -- otherwise we just start with the parent's owners.
331
- deepestCommon !== -1 ? childOwners[deepestCommon].getName() || UNKNOWN : [], ancestorOwnerNames, ancestorTag,
332
- // If we're warning about an invalid (non-parent) ancestry, add '...'
333
- invalidAncestor ? ['...'] : [], childOwnerNames, childTag).join(' > ');
334
-
335
- var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + ownerInfo;
336
- if (didWarn[warnKey]) {
337
- return;
338
- }
339
- didWarn[warnKey] = true;
340
-
341
- var tagDisplayName = childTag;
342
- if (childTag !== '#text') {
343
- tagDisplayName = '<' + childTag + '>';
344
- }
345
-
346
- if (invalidParent) {
347
- var info = '';
348
- if (ancestorTag === 'table' && childTag === 'tr') {
349
- info += ' Add a <tbody> to your code to match the DOM tree generated by ' + 'the browser.';
350
- }
351
- process.env.NODE_ENV !== 'production' ? warning(false, 'validateDOMNesting(...): %s cannot appear as a child of <%s>. ' + 'See %s.%s', tagDisplayName, ancestorTag, ownerInfo, info) : void 0;
352
- } else {
353
- process.env.NODE_ENV !== 'production' ? warning(false, 'validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>. See %s.', tagDisplayName, ancestorTag, ownerInfo) : void 0;
354
- }
355
- }
356
- };
357
-
358
- validateDOMNesting.updatedAncestorInfo = updatedAncestorInfo;
359
-
360
- // For testing
361
- validateDOMNesting.isTagValidInContext = function (tag, ancestorInfo) {
362
- ancestorInfo = ancestorInfo || emptyAncestorInfo;
363
- var parentInfo = ancestorInfo.current;
364
- var parentTag = parentInfo && parentInfo.tag;
365
- return isTagValidWithParent(tag, parentTag) && !findInvalidAncestorForTag(tag, ancestorInfo);
366
- };
367
- }
368
-
369
- module.exports = validateDOMNesting;