From bbff7403fbf46f9ad92240ac213df8d30ef31b64 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Thu, 20 Sep 2018 02:56:13 +0200 Subject: update packages --- .../cjs/react-dom-server.browser.development.js | 1702 +++++++++++++------- 1 file changed, 1136 insertions(+), 566 deletions(-) (limited to 'node_modules/react-dom/cjs/react-dom-server.browser.development.js') diff --git a/node_modules/react-dom/cjs/react-dom-server.browser.development.js b/node_modules/react-dom/cjs/react-dom-server.browser.development.js index dcf78c70d..dd13e823b 100644 --- a/node_modules/react-dom/cjs/react-dom-server.browser.development.js +++ b/node_modules/react-dom/cjs/react-dom-server.browser.development.js @@ -1,7 +1,7 @@ -/** @license React v16.2.0 +/** @license React v16.5.2 * react-dom-server.browser.development.js * - * Copyright (c) 2013-present, Facebook, Inc. + * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. @@ -15,411 +15,656 @@ if (process.env.NODE_ENV !== "production") { (function() { 'use strict'; -var invariant = require('fbjs/lib/invariant'); var _assign = require('object-assign'); var React = require('react'); -var emptyFunction = require('fbjs/lib/emptyFunction'); -var emptyObject = require('fbjs/lib/emptyObject'); -var hyphenateStyleName = require('fbjs/lib/hyphenateStyleName'); -var memoizeStringOnly = require('fbjs/lib/memoizeStringOnly'); -var warning = require('fbjs/lib/warning'); var checkPropTypes = require('prop-types/checkPropTypes'); -var camelizeStyleName = require('fbjs/lib/camelizeStyleName'); /** - * WARNING: DO NOT manually require this module. - * This is a replacement for `invariant(...)` used by the error code system - * and will _only_ be required by the corresponding babel pass. - * It always throws. + * Use invariant() to assert state which your program assumes to be true. + * + * Provide sprintf-style format (only %s is supported) and arguments + * to provide information about what broke and what you were + * expecting. + * + * The invariant message will be stripped in production, but the invariant + * will remain to ensure logic does not differ in production. */ -// These attributes should be all lowercase to allow for -// case insensitive checks -var RESERVED_PROPS = { - children: true, - dangerouslySetInnerHTML: true, - defaultValue: true, - defaultChecked: true, - innerHTML: true, - suppressContentEditableWarning: true, - suppressHydrationWarning: true, - style: true -}; +var validateFormat = function () {}; -function checkMask(value, bitmask) { - return (value & bitmask) === bitmask; +{ + validateFormat = function (format) { + if (format === undefined) { + throw new Error('invariant requires an error message argument'); + } + }; } -var DOMPropertyInjection = { - /** - * Mapping from normalized, camelcased property names to a configuration that - * specifies how the associated DOM property should be accessed or rendered. - */ - MUST_USE_PROPERTY: 0x1, - HAS_BOOLEAN_VALUE: 0x4, - HAS_NUMERIC_VALUE: 0x8, - HAS_POSITIVE_NUMERIC_VALUE: 0x10 | 0x8, - HAS_OVERLOADED_BOOLEAN_VALUE: 0x20, - HAS_STRING_BOOLEAN_VALUE: 0x40, +function invariant(condition, format, a, b, c, d, e, f) { + validateFormat(format); - /** - * Inject some specialized knowledge about the DOM. This takes a config object - * with the following properties: - * - * Properties: object mapping DOM property name to one of the - * DOMPropertyInjection constants or null. If your attribute isn't in here, - * it won't get written to the DOM. - * - * DOMAttributeNames: object mapping React attribute name to the DOM - * attribute name. Attribute names not specified use the **lowercase** - * normalized name. - * - * DOMAttributeNamespaces: object mapping React attribute name to the DOM - * attribute namespace URL. (Attribute names not specified use no namespace.) - * - * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties. - * Property names not specified use the normalized name. - * - * DOMMutationMethods: Properties that require special mutation methods. If - * `value` is undefined, the mutation method should unset the property. - * - * @param {object} domPropertyConfig the config as described above. - */ - injectDOMPropertyConfig: function (domPropertyConfig) { - var Injection = DOMPropertyInjection; - var Properties = domPropertyConfig.Properties || {}; - var DOMAttributeNamespaces = domPropertyConfig.DOMAttributeNamespaces || {}; - var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {}; - var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {}; - - for (var propName in Properties) { - !!properties.hasOwnProperty(propName) ? invariant(false, "injectDOMPropertyConfig(...): You're trying to inject DOM property '%s' which has already been injected. You may be accidentally injecting the same DOM property config twice, or you may be injecting two configs that have conflicting property names.", propName) : void 0; - - var lowerCased = propName.toLowerCase(); - var propConfig = Properties[propName]; - - var propertyInfo = { - attributeName: lowerCased, - attributeNamespace: null, - propertyName: propName, - mutationMethod: null, - - mustUseProperty: checkMask(propConfig, Injection.MUST_USE_PROPERTY), - hasBooleanValue: checkMask(propConfig, Injection.HAS_BOOLEAN_VALUE), - hasNumericValue: checkMask(propConfig, Injection.HAS_NUMERIC_VALUE), - hasPositiveNumericValue: checkMask(propConfig, Injection.HAS_POSITIVE_NUMERIC_VALUE), - hasOverloadedBooleanValue: checkMask(propConfig, Injection.HAS_OVERLOADED_BOOLEAN_VALUE), - hasStringBooleanValue: checkMask(propConfig, Injection.HAS_STRING_BOOLEAN_VALUE) - }; - !(propertyInfo.hasBooleanValue + propertyInfo.hasNumericValue + propertyInfo.hasOverloadedBooleanValue <= 1) ? invariant(false, "DOMProperty: Value can be one of boolean, overloaded boolean, or numeric value, but not a combination: %s", propName) : void 0; - - if (DOMAttributeNames.hasOwnProperty(propName)) { - var attributeName = DOMAttributeNames[propName]; - - propertyInfo.attributeName = attributeName; + if (!condition) { + var error = void 0; + if (format === undefined) { + error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.'); + } else { + var args = [a, b, c, d, e, f]; + var argIndex = 0; + error = new Error(format.replace(/%s/g, function () { + return args[argIndex++]; + })); + error.name = 'Invariant Violation'; + } + + error.framesToPop = 1; // we don't care about invariant's own frame + throw error; + } +} + +// Relying on the `invariant()` implementation lets us +// preserve the format and params in the www builds. + +// TODO: this is special because it gets imported during build. + +var ReactVersion = '16.5.2'; + +/** + * Similar to invariant but only logs a warning if the condition is not met. + * This can be used to log issues in development environments in critical + * paths. Removing the logging code for production environments will keep the + * same logic and follow the same code paths. + */ + +var warningWithoutStack = function () {}; + +{ + warningWithoutStack = function (condition, format) { + for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { + args[_key - 2] = arguments[_key]; + } + + if (format === undefined) { + throw new Error('`warningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument'); + } + if (args.length > 8) { + // Check before the condition to catch violations early. + throw new Error('warningWithoutStack() currently supports at most 8 arguments.'); + } + if (condition) { + return; + } + if (typeof console !== 'undefined') { + var _args$map = args.map(function (item) { + return '' + item; + }), + a = _args$map[0], + b = _args$map[1], + c = _args$map[2], + d = _args$map[3], + e = _args$map[4], + f = _args$map[5], + g = _args$map[6], + h = _args$map[7]; + + var message = 'Warning: ' + format; + + // We intentionally don't use spread (or .apply) because it breaks IE9: + // https://github.com/facebook/react/issues/13610 + switch (args.length) { + case 0: + console.error(message); + break; + case 1: + console.error(message, a); + break; + case 2: + console.error(message, a, b); + break; + case 3: + console.error(message, a, b, c); + break; + case 4: + console.error(message, a, b, c, d); + break; + case 5: + console.error(message, a, b, c, d, e); + break; + case 6: + console.error(message, a, b, c, d, e, f); + break; + case 7: + console.error(message, a, b, c, d, e, f, g); + break; + case 8: + console.error(message, a, b, c, d, e, f, g, h); + break; + default: + throw new Error('warningWithoutStack() currently supports at most 8 arguments.'); } + } + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + var argIndex = 0; + var _message = 'Warning: ' + format.replace(/%s/g, function () { + return args[argIndex++]; + }); + throw new Error(_message); + } catch (x) {} + }; +} + +var warningWithoutStack$1 = warningWithoutStack; - if (DOMAttributeNamespaces.hasOwnProperty(propName)) { - propertyInfo.attributeNamespace = DOMAttributeNamespaces[propName]; +// The Symbol used to tag the ReactElement-like types. If there is no native Symbol +// nor polyfill, then a plain number is used for performance. +var hasSymbol = typeof Symbol === 'function' && Symbol.for; + + +var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca; +var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb; +var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc; +var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2; +var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd; +var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace; +var REACT_ASYNC_MODE_TYPE = hasSymbol ? Symbol.for('react.async_mode') : 0xeacf; +var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0; +var REACT_PLACEHOLDER_TYPE = hasSymbol ? Symbol.for('react.placeholder') : 0xead1; + +var Resolved = 1; + + + + +function refineResolvedThenable(thenable) { + return thenable._reactStatus === Resolved ? thenable._reactResult : null; +} + +function getComponentName(type) { + if (type == null) { + // Host root, text node or just invalid type. + return null; + } + { + if (typeof type.tag === 'number') { + warningWithoutStack$1(false, 'Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.'); + } + } + if (typeof type === 'function') { + return type.displayName || type.name || null; + } + if (typeof type === 'string') { + return type; + } + switch (type) { + case REACT_ASYNC_MODE_TYPE: + return 'AsyncMode'; + case REACT_FRAGMENT_TYPE: + return 'Fragment'; + case REACT_PORTAL_TYPE: + return 'Portal'; + case REACT_PROFILER_TYPE: + return 'Profiler'; + case REACT_STRICT_MODE_TYPE: + return 'StrictMode'; + case REACT_PLACEHOLDER_TYPE: + return 'Placeholder'; + } + if (typeof type === 'object') { + switch (type.$$typeof) { + case REACT_CONTEXT_TYPE: + return 'Context.Consumer'; + case REACT_PROVIDER_TYPE: + return 'Context.Provider'; + case REACT_FORWARD_REF_TYPE: + var renderFn = type.render; + var functionName = renderFn.displayName || renderFn.name || ''; + return type.displayName || (functionName !== '' ? 'ForwardRef(' + functionName + ')' : 'ForwardRef'); + } + if (typeof type.then === 'function') { + var thenable = type; + var resolvedThenable = refineResolvedThenable(thenable); + if (resolvedThenable) { + return getComponentName(resolvedThenable); } + } + } + return null; +} - if (DOMMutationMethods.hasOwnProperty(propName)) { - propertyInfo.mutationMethod = DOMMutationMethods[propName]; +/** + * Forked from fbjs/warning: + * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js + * + * Only change is we use console.warn instead of console.error, + * and do nothing when 'console' is not supported. + * This really simplifies the code. + * --- + * Similar to invariant but only logs a warning if the condition is not met. + * This can be used to log issues in development environments in critical + * paths. Removing the logging code for production environments will keep the + * same logic and follow the same code paths. + */ + +var lowPriorityWarning = function () {}; + +{ + var printWarning = function (format) { + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + var argIndex = 0; + var message = 'Warning: ' + format.replace(/%s/g, function () { + return args[argIndex++]; + }); + if (typeof console !== 'undefined') { + console.warn(message); + } + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + throw new Error(message); + } catch (x) {} + }; + + lowPriorityWarning = function (condition, format) { + if (format === undefined) { + throw new Error('`lowPriorityWarning(condition, format, ...args)` requires a warning ' + 'message argument'); + } + if (!condition) { + for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { + args[_key2 - 2] = arguments[_key2]; } - // Downcase references to whitelist properties to check for membership - // without case-sensitivity. This allows the whitelist to pick up - // `allowfullscreen`, which should be written using the property configuration - // for `allowFullscreen` - properties[propName] = propertyInfo; + printWarning.apply(undefined, [format].concat(args)); } + }; +} + +var lowPriorityWarning$1 = lowPriorityWarning; + +var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; + +/** + * Similar to invariant but only logs a warning if the condition is not met. + * This can be used to log issues in development environments in critical + * paths. Removing the logging code for production environments will keep the + * same logic and follow the same code paths. + */ + +var warning = warningWithoutStack$1; + +{ + warning = function (condition, format) { + if (condition) { + return; + } + var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + var stack = ReactDebugCurrentFrame.getStackAddendum(); + // eslint-disable-next-line react-internal/warning-and-invariant-args + + for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { + args[_key - 2] = arguments[_key]; + } + + warningWithoutStack$1.apply(undefined, [false, format + '%s'].concat(args, [stack])); + }; +} + +var warning$1 = warning; + +var BEFORE_SLASH_RE = /^(.*)[\\\/]/; + +var describeComponentFrame = function (name, source, ownerName) { + var sourceInfo = ''; + if (source) { + var path = source.fileName; + var fileName = path.replace(BEFORE_SLASH_RE, ''); + { + // In DEV, include code for a common special case: + // prefer "folder/index.js" instead of just "index.js". + if (/^index\./.test(fileName)) { + var match = path.match(BEFORE_SLASH_RE); + if (match) { + var pathBeforeSlash = match[1]; + if (pathBeforeSlash) { + var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ''); + fileName = folderName + '/' + fileName; + } + } + } + } + sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')'; + } else if (ownerName) { + sourceInfo = ' (created by ' + ownerName + ')'; } + return '\n in ' + (name || 'Unknown') + sourceInfo; }; +// Exports ReactDOM.createRoot + + +// Experimental error-boundary API that can recover from errors within a single +// render phase + +// Suspense + +// Helps identify side effects in begin-phase lifecycle hooks and setState reducers: + + +// In some cases, StrictMode should also double-render lifecycles. +// This can be confusing for tests though, +// And it can be bad for performance in production. +// This feature flag can be used to control the behavior: + + +// To preserve the "Pause on caught exceptions" behavior of the debugger, we +// replay the begin phase of a failed component inside invokeGuardedCallback. + + +// Warn about deprecated, async-unsafe lifecycles; relates to RFC #6: +var warnAboutDeprecatedLifecycles = false; + +// Warn about legacy context API + + +// Gather advanced timing metrics for Profiler subtrees. + + +// Trace which interactions trigger each commit. + + +// Only used in www builds. +var enableSuspenseServerRenderer = false; + +// Only used in www builds. + + +// React Fire: prevent the value and checked attributes from syncing +// with their related DOM properties + +// A reserved attribute. +// It is handled by React separately and shouldn't be written to the DOM. +var RESERVED = 0; + +// A simple string attribute. +// Attributes that aren't in the whitelist are presumed to have this type. +var STRING = 1; + +// A string attribute that accepts booleans in React. In HTML, these are called +// "enumerated" attributes with "true" and "false" as possible values. +// When true, it should be set to a "true" string. +// When false, it should be set to a "false" string. +var BOOLEANISH_STRING = 2; + +// A real boolean attribute. +// When true, it should be present (set either to an empty string or its name). +// When false, it should be omitted. +var BOOLEAN = 3; + +// An attribute that can be used as a flag as well as with a value. +// When true, it should be present (set either to an empty string or its name). +// When false, it should be omitted. +// For any other value, should be present with that value. +var OVERLOADED_BOOLEAN = 4; + +// An attribute that must be numeric or parse as a numeric. +// When falsy, it should be removed. +var NUMERIC = 5; + +// An attribute that must be positive numeric or parse as a positive numeric. +// When falsy, it should be removed. +var POSITIVE_NUMERIC = 6; + /* eslint-disable max-len */ -var ATTRIBUTE_NAME_START_CHAR = ":A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD"; +var ATTRIBUTE_NAME_START_CHAR = ':A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD'; /* eslint-enable max-len */ -var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + "\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040"; +var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + '\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040'; var ROOT_ATTRIBUTE_NAME = 'data-reactroot'; +var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$'); -/** - * Map from property "standard name" to an object with info about how to set - * the property in the DOM. Each object contains: - * - * attributeName: - * Used when rendering markup or with `*Attribute()`. - * attributeNamespace - * propertyName: - * Used on DOM node instances. (This includes properties that mutate due to - * external factors.) - * mutationMethod: - * If non-null, used instead of the property or `setAttribute()` after - * initial render. - * mustUseProperty: - * Whether the property must be accessed and mutated as an object property. - * hasBooleanValue: - * Whether the property should be removed when set to a falsey value. - * hasNumericValue: - * Whether the property must be numeric or parse as a numeric and should be - * removed when set to a falsey value. - * hasPositiveNumericValue: - * Whether the property must be positive numeric or parse as a positive - * numeric and should be removed when set to a falsey value. - * hasOverloadedBooleanValue: - * Whether the property can be used as a flag as well as with a value. - * Removed when strictly equal to false; present without a value when - * strictly equal to true; present with a value otherwise. - */ -var properties = {}; +var hasOwnProperty$1 = Object.prototype.hasOwnProperty; +var illegalAttributeNameCache = {}; +var validatedAttributeNameCache = {}; -/** - * Checks whether a property name is a writeable attribute. - * @method - */ -function shouldSetAttribute(name, value) { - if (isReservedProp(name)) { +function isAttributeNameSafe(attributeName) { + if (hasOwnProperty$1.call(validatedAttributeNameCache, attributeName)) { + return true; + } + if (hasOwnProperty$1.call(illegalAttributeNameCache, attributeName)) { return false; } - if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) { + if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) { + validatedAttributeNameCache[attributeName] = true; + return true; + } + illegalAttributeNameCache[attributeName] = true; + { + warning$1(false, 'Invalid attribute name: `%s`', attributeName); + } + return false; +} + +function shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) { + if (propertyInfo !== null) { + return propertyInfo.type === RESERVED; + } + if (isCustomComponentTag) { return false; } - if (value === null) { + if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) { return true; } + return false; +} + +function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) { + if (propertyInfo !== null && propertyInfo.type === RESERVED) { + return false; + } switch (typeof value) { - case 'boolean': - return shouldAttributeAcceptBooleanValue(name); - case 'undefined': - case 'number': - case 'string': - case 'object': + case 'function': + // $FlowIssue symbol is perfectly valid here + case 'symbol': + // eslint-disable-line return true; + case 'boolean': + { + if (isCustomComponentTag) { + return false; + } + if (propertyInfo !== null) { + return !propertyInfo.acceptsBooleans; + } else { + var prefix = name.toLowerCase().slice(0, 5); + return prefix !== 'data-' && prefix !== 'aria-'; + } + } default: - // function, symbol return false; } } -function getPropertyInfo(name) { - return properties.hasOwnProperty(name) ? properties[name] : null; -} - -function shouldAttributeAcceptBooleanValue(name) { - if (isReservedProp(name)) { +function shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) { + if (value === null || typeof value === 'undefined') { return true; } - var propertyInfo = getPropertyInfo(name); - if (propertyInfo) { - return propertyInfo.hasBooleanValue || propertyInfo.hasStringBooleanValue || propertyInfo.hasOverloadedBooleanValue; + if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) { + return true; } - var prefix = name.toLowerCase().slice(0, 5); - return prefix === 'data-' || prefix === 'aria-'; -} - -/** - * Checks to see if a property name is within the list of properties - * reserved for internal React operations. These properties should - * not be set on an HTML element. - * - * @private - * @param {string} name - * @return {boolean} If the name is within reserved props - */ -function isReservedProp(name) { - return RESERVED_PROPS.hasOwnProperty(name); -} - -var injection = DOMPropertyInjection; - -var MUST_USE_PROPERTY = injection.MUST_USE_PROPERTY; -var HAS_BOOLEAN_VALUE = injection.HAS_BOOLEAN_VALUE; -var HAS_NUMERIC_VALUE = injection.HAS_NUMERIC_VALUE; -var HAS_POSITIVE_NUMERIC_VALUE = injection.HAS_POSITIVE_NUMERIC_VALUE; -var HAS_OVERLOADED_BOOLEAN_VALUE = injection.HAS_OVERLOADED_BOOLEAN_VALUE; -var HAS_STRING_BOOLEAN_VALUE = injection.HAS_STRING_BOOLEAN_VALUE; - -var HTMLDOMPropertyConfig = { - // When adding attributes to this list, be sure to also add them to - // the `possibleStandardNames` module to ensure casing and incorrect - // name warnings. - Properties: { - allowFullScreen: HAS_BOOLEAN_VALUE, - // specifies target context for links with `preload` type - async: HAS_BOOLEAN_VALUE, - // Note: there is a special case that prevents it from being written to the DOM - // on the client side because the browsers are inconsistent. Instead we call focus(). - autoFocus: HAS_BOOLEAN_VALUE, - autoPlay: HAS_BOOLEAN_VALUE, - capture: HAS_OVERLOADED_BOOLEAN_VALUE, - checked: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - cols: HAS_POSITIVE_NUMERIC_VALUE, - contentEditable: HAS_STRING_BOOLEAN_VALUE, - controls: HAS_BOOLEAN_VALUE, - 'default': HAS_BOOLEAN_VALUE, - defer: HAS_BOOLEAN_VALUE, - disabled: HAS_BOOLEAN_VALUE, - download: HAS_OVERLOADED_BOOLEAN_VALUE, - draggable: HAS_STRING_BOOLEAN_VALUE, - formNoValidate: HAS_BOOLEAN_VALUE, - hidden: HAS_BOOLEAN_VALUE, - loop: HAS_BOOLEAN_VALUE, - // Caution; `option.selected` is not updated if `select.multiple` is - // disabled with `removeAttribute`. - multiple: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - muted: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - noValidate: HAS_BOOLEAN_VALUE, - open: HAS_BOOLEAN_VALUE, - playsInline: HAS_BOOLEAN_VALUE, - readOnly: HAS_BOOLEAN_VALUE, - required: HAS_BOOLEAN_VALUE, - reversed: HAS_BOOLEAN_VALUE, - rows: HAS_POSITIVE_NUMERIC_VALUE, - rowSpan: HAS_NUMERIC_VALUE, - scoped: HAS_BOOLEAN_VALUE, - seamless: HAS_BOOLEAN_VALUE, - selected: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE, - size: HAS_POSITIVE_NUMERIC_VALUE, - start: HAS_NUMERIC_VALUE, - // support for projecting regular DOM Elements via V1 named slots ( shadow dom ) - span: HAS_POSITIVE_NUMERIC_VALUE, - spellCheck: HAS_STRING_BOOLEAN_VALUE, - // Style must be explicitly set in the attribute list. React components - // expect a style object - style: 0, - // Keep it in the whitelist because it is case-sensitive for SVG. - tabIndex: 0, - // itemScope is for for Microdata support. - // See http://schema.org/docs/gs.html - itemScope: HAS_BOOLEAN_VALUE, - // These attributes must stay in the white-list because they have - // different attribute names (see DOMAttributeNames below) - acceptCharset: 0, - className: 0, - htmlFor: 0, - httpEquiv: 0, - // Attributes with mutation methods must be specified in the whitelist - // Set the string boolean flag to allow the behavior - value: HAS_STRING_BOOLEAN_VALUE - }, - DOMAttributeNames: { - acceptCharset: 'accept-charset', - className: 'class', - htmlFor: 'for', - httpEquiv: 'http-equiv' - }, - DOMMutationMethods: { - value: function (node, value) { - if (value == null) { - return node.removeAttribute('value'); - } - - // Number inputs get special treatment due to some edge cases in - // Chrome. Let everything else assign the value attribute as normal. - // https://github.com/facebook/react/issues/7253#issuecomment-236074326 - if (node.type !== 'number' || node.hasAttribute('value') === false) { - node.setAttribute('value', '' + value); - } else if (node.validity && !node.validity.badInput && node.ownerDocument.activeElement !== node) { - // Don't assign an attribute if validation reports bad - // input. Chrome will clear the value. Additionally, don't - // operate on inputs that have focus, otherwise Chrome might - // strip off trailing decimal places and cause the user's - // cursor position to jump to the beginning of the input. - // - // In ReactDOMInput, we have an onBlur event that will trigger - // this function again when focus is lost. - node.setAttribute('value', '' + value); - } + if (isCustomComponentTag) { + return false; + } + if (propertyInfo !== null) { + switch (propertyInfo.type) { + case BOOLEAN: + return !value; + case OVERLOADED_BOOLEAN: + return value === false; + case NUMERIC: + return isNaN(value); + case POSITIVE_NUMERIC: + return isNaN(value) || value < 1; } } -}; + return false; +} -var HAS_STRING_BOOLEAN_VALUE$1 = injection.HAS_STRING_BOOLEAN_VALUE; +function getPropertyInfo(name) { + return properties.hasOwnProperty(name) ? properties[name] : null; +} +function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace) { + this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN; + this.attributeName = attributeName; + this.attributeNamespace = attributeNamespace; + this.mustUseProperty = mustUseProperty; + this.propertyName = name; + this.type = type; +} -var NS = { - xlink: 'http://www.w3.org/1999/xlink', - xml: 'http://www.w3.org/XML/1998/namespace' -}; +// When adding attributes to this list, be sure to also add them to +// the `possibleStandardNames` module to ensure casing and incorrect +// name warnings. +var properties = {}; -/** - * This is a list of all SVG attributes that need special casing, - * namespacing, or boolean value assignment. - * - * When adding attributes to this list, be sure to also add them to - * the `possibleStandardNames` module to ensure casing and incorrect - * name warnings. - * - * SVG Attributes List: - * https://www.w3.org/TR/SVG/attindex.html - * SMIL Spec: - * https://www.w3.org/TR/smil - */ -var ATTRS = ['accent-height', 'alignment-baseline', 'arabic-form', 'baseline-shift', 'cap-height', 'clip-path', 'clip-rule', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'dominant-baseline', 'enable-background', 'fill-opacity', 'fill-rule', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'glyph-name', 'glyph-orientation-horizontal', 'glyph-orientation-vertical', 'horiz-adv-x', 'horiz-origin-x', 'image-rendering', 'letter-spacing', 'lighting-color', 'marker-end', 'marker-mid', 'marker-start', 'overline-position', 'overline-thickness', 'paint-order', 'panose-1', 'pointer-events', 'rendering-intent', 'shape-rendering', 'stop-color', 'stop-opacity', 'strikethrough-position', 'strikethrough-thickness', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'text-anchor', 'text-decoration', 'text-rendering', 'underline-position', 'underline-thickness', 'unicode-bidi', 'unicode-range', 'units-per-em', 'v-alphabetic', 'v-hanging', 'v-ideographic', 'v-mathematical', 'vector-effect', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'word-spacing', 'writing-mode', 'x-height', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xmlns:xlink', 'xml:lang', 'xml:space']; - -var SVGDOMPropertyConfig = { - Properties: { - autoReverse: HAS_STRING_BOOLEAN_VALUE$1, - externalResourcesRequired: HAS_STRING_BOOLEAN_VALUE$1, - preserveAlpha: HAS_STRING_BOOLEAN_VALUE$1 - }, - DOMAttributeNames: { - autoReverse: 'autoReverse', - externalResourcesRequired: 'externalResourcesRequired', - preserveAlpha: 'preserveAlpha' - }, - DOMAttributeNamespaces: { - xlinkActuate: NS.xlink, - xlinkArcrole: NS.xlink, - xlinkHref: NS.xlink, - xlinkRole: NS.xlink, - xlinkShow: NS.xlink, - xlinkTitle: NS.xlink, - xlinkType: NS.xlink, - xmlBase: NS.xml, - xmlLang: NS.xml, - xmlSpace: NS.xml - } -}; +// These props are reserved by React. They shouldn't be written to the DOM. +['children', 'dangerouslySetInnerHTML', +// TODO: This prevents the assignment of defaultValue to regular +// elements (not just inputs). Now that ReactDOMInput assigns to the +// defaultValue property -- do we need this? +'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style'].forEach(function (name) { + properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty + name, // attributeName + null); +} // attributeNamespace +); + +// A few React string attributes have a different name. +// This is a mapping from React prop names to the attribute names. +[['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']].forEach(function (_ref) { + var name = _ref[0], + attributeName = _ref[1]; + + properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty + attributeName, // attributeName + null); +} // attributeNamespace +); + +// These are "enumerated" HTML attributes that accept "true" and "false". +// In React, we let users pass `true` and `false` even though technically +// these aren't boolean attributes (they are coerced to strings). +['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) { + properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty + name.toLowerCase(), // attributeName + null); +} // attributeNamespace +); + +// These are "enumerated" SVG attributes that accept "true" and "false". +// In React, we let users pass `true` and `false` even though technically +// these aren't boolean attributes (they are coerced to strings). +// Since these are SVG attributes, their attribute names are case-sensitive. +['autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha'].forEach(function (name) { + properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty + name, // attributeName + null); +} // attributeNamespace +); + +// These are HTML boolean attributes. +['allowFullScreen', 'async', +// Note: there is a special case that prevents it from being written to the DOM +// on the client side because the browsers are inconsistent. Instead we call focus(). +'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless', +// Microdata +'itemScope'].forEach(function (name) { + properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty + name.toLowerCase(), // attributeName + null); +} // attributeNamespace +); + +// These are the few React props that we set as DOM properties +// rather than attributes. These are all booleans. +['checked', +// Note: `option.selected` is not updated if `select.multiple` is +// disabled with `removeAttribute`. We have special logic for handling this. +'multiple', 'muted', 'selected'].forEach(function (name) { + properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty + name, // attributeName + null); +} // attributeNamespace +); + +// These are HTML attributes that are "overloaded booleans": they behave like +// booleans, but can also accept a string value. +['capture', 'download'].forEach(function (name) { + properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty + name, // attributeName + null); +} // attributeNamespace +); + +// These are HTML attributes that must be positive numbers. +['cols', 'rows', 'size', 'span'].forEach(function (name) { + properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty + name, // attributeName + null); +} // attributeNamespace +); + +// These are HTML attributes that must be numbers. +['rowSpan', 'start'].forEach(function (name) { + properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty + name.toLowerCase(), // attributeName + null); +} // attributeNamespace +); var CAMELIZE = /[\-\:]([a-z])/g; var capitalize = function (token) { return token[1].toUpperCase(); }; -ATTRS.forEach(function (original) { - var reactName = original.replace(CAMELIZE, capitalize); - - SVGDOMPropertyConfig.Properties[reactName] = 0; - SVGDOMPropertyConfig.DOMAttributeNames[reactName] = original; +// This is a list of all SVG attributes that need special casing, namespacing, +// or boolean value assignment. Regular attributes that just accept strings +// and have the same names are omitted, just like in the HTML whitelist. +// Some of these attributes can be hard to find. This list was created by +// scrapping the MDN documentation. +['accent-height', 'alignment-baseline', 'arabic-form', 'baseline-shift', 'cap-height', 'clip-path', 'clip-rule', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'dominant-baseline', 'enable-background', 'fill-opacity', 'fill-rule', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'glyph-name', 'glyph-orientation-horizontal', 'glyph-orientation-vertical', 'horiz-adv-x', 'horiz-origin-x', 'image-rendering', 'letter-spacing', 'lighting-color', 'marker-end', 'marker-mid', 'marker-start', 'overline-position', 'overline-thickness', 'paint-order', 'panose-1', 'pointer-events', 'rendering-intent', 'shape-rendering', 'stop-color', 'stop-opacity', 'strikethrough-position', 'strikethrough-thickness', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'text-anchor', 'text-decoration', 'text-rendering', 'underline-position', 'underline-thickness', 'unicode-bidi', 'unicode-range', 'units-per-em', 'v-alphabetic', 'v-hanging', 'v-ideographic', 'v-mathematical', 'vector-effect', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'word-spacing', 'writing-mode', 'xmlns:xlink', 'x-height'].forEach(function (attributeName) { + var name = attributeName.replace(CAMELIZE, capitalize); + properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty + attributeName, null); +} // attributeNamespace +); + +// String SVG attributes with the xlink namespace. +['xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type'].forEach(function (attributeName) { + var name = attributeName.replace(CAMELIZE, capitalize); + properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty + attributeName, 'http://www.w3.org/1999/xlink'); }); -injection.injectDOMPropertyConfig(HTMLDOMPropertyConfig); -injection.injectDOMPropertyConfig(SVGDOMPropertyConfig); - -// TODO: this is special because it gets imported during build. - -var ReactVersion = '16.2.0'; - -var describeComponentFrame = function (name, source, ownerName) { - return '\n in ' + (name || 'Unknown') + (source ? ' (at ' + source.fileName.replace(/^.*[\\\/]/, '') + ':' + source.lineNumber + ')' : ownerName ? ' (created by ' + ownerName + ')' : ''); -}; - -var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; - -var ReactCurrentOwner = ReactInternals.ReactCurrentOwner; -var ReactDebugCurrentFrame = ReactInternals.ReactDebugCurrentFrame; - -// The Symbol used to tag the ReactElement-like types. If there is no native Symbol -// nor polyfill, then a plain number is used for performance. -var hasSymbol = typeof Symbol === 'function' && Symbol['for']; - - - - +// String SVG attributes with the xml namespace. +['xml:base', 'xml:lang', 'xml:space'].forEach(function (attributeName) { + var name = attributeName.replace(CAMELIZE, capitalize); + properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty + attributeName, 'http://www.w3.org/XML/1998/namespace'); +}); -var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol['for']('react.fragment') : 0xeacb; +// Special case: this attribute exists both in HTML and SVG. +// Its "tabindex" attribute name is case-sensitive in SVG so we can't just use +// its React `tabIndex` name, like we do for attributes that exist only in HTML. +properties.tabIndex = new PropertyInfoRecord('tabIndex', STRING, false, // mustUseProperty +'tabindex', // attributeName +null); // code copied and modified from escape-html /** @@ -445,7 +690,7 @@ function escapeHtml(string) { return str; } - var escape; + var escape = void 0; var html = ''; var index = 0; var lastIndex = 0; @@ -514,35 +759,6 @@ function quoteAttributeValueForBrowser(value) { return '"' + escapeTextForBrowser(value) + '"'; } -// isAttributeNameSafe() is currently duplicated in DOMPropertyOperations. -// TODO: Find a better place for this. -var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$'); -var illegalAttributeNameCache = {}; -var validatedAttributeNameCache = {}; -function isAttributeNameSafe(attributeName) { - if (validatedAttributeNameCache.hasOwnProperty(attributeName)) { - return true; - } - if (illegalAttributeNameCache.hasOwnProperty(attributeName)) { - return false; - } - if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) { - validatedAttributeNameCache[attributeName] = true; - return true; - } - illegalAttributeNameCache[attributeName] = true; - { - warning(false, 'Invalid attribute name: `%s`', attributeName); - } - return false; -} - -// shouldIgnoreValue() is currently duplicated in DOMPropertyOperations. -// TODO: Find a better place for this. -function shouldIgnoreValue(propertyInfo, value) { - return value == null || propertyInfo.hasBooleanValue && !value || propertyInfo.hasNumericValue && isNaN(value) || propertyInfo.hasPositiveNumericValue && value < 1 || propertyInfo.hasOverloadedBooleanValue && value === false; -} - /** * Operations for dealing with DOM properties. */ @@ -568,23 +784,25 @@ function createMarkupForRoot() { */ function createMarkupForProperty(name, value) { var propertyInfo = getPropertyInfo(name); - if (propertyInfo) { - if (shouldIgnoreValue(propertyInfo, value)) { - return ''; - } + if (name !== 'style' && shouldIgnoreAttribute(name, propertyInfo, false)) { + return ''; + } + if (shouldRemoveAttribute(name, value, propertyInfo, false)) { + return ''; + } + if (propertyInfo !== null) { var attributeName = propertyInfo.attributeName; - if (propertyInfo.hasBooleanValue || propertyInfo.hasOverloadedBooleanValue && value === true) { + var type = propertyInfo.type; + + if (type === BOOLEAN || type === OVERLOADED_BOOLEAN && value === true) { return attributeName + '=""'; - } else if (typeof value !== 'boolean' || shouldAttributeAcceptBooleanValue(name)) { + } else { return attributeName + '=' + quoteAttributeValueForBrowser(value); } - } else if (shouldSetAttribute(name, value)) { - if (value == null) { - return ''; - } + } else if (isAttributeNameSafe(name)) { return name + '=' + quoteAttributeValueForBrowser(value); } - return null; + return ''; } /** @@ -636,11 +854,15 @@ function getChildNamespace(parentNamespace, type) { return parentNamespace; } +var ReactDebugCurrentFrame$1 = null; + var ReactControlledValuePropTypes = { checkPropTypes: null }; { + ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame; + var hasReadOnlyValue = { button: true, checkbox: true, @@ -653,13 +875,13 @@ var ReactControlledValuePropTypes = { var propTypes = { value: function (props, propName, componentName) { - if (!props[propName] || hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled) { + if (hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled || props[propName] == null) { return null; } return new Error('You provided a `value` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultValue`. Otherwise, ' + 'set either `onChange` or `readOnly`.'); }, checked: function (props, propName, componentName) { - if (!props[propName] || props.onChange || props.readOnly || props.disabled) { + if (props.onChange || props.readOnly || props.disabled || props[propName] == null) { return null; } return new Error('You provided a `checked` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultChecked`. Otherwise, ' + 'set either `onChange` or `readOnly`.'); @@ -670,8 +892,8 @@ var ReactControlledValuePropTypes = { * Provide a linked `value` attribute for controlled forms. You should not use * this outside of the ReactDOM controlled form components. */ - ReactControlledValuePropTypes.checkPropTypes = function (tagName, props, getStack) { - checkPropTypes(propTypes, props, 'prop', tagName, getStack); + ReactControlledValuePropTypes.checkPropTypes = function (tagName, props) { + checkPropTypes(propTypes, props, 'prop', tagName, ReactDebugCurrentFrame$1.getStackAddendum); }; } @@ -694,6 +916,7 @@ var omittedCloseTags = { source: true, track: true, wbr: true + // NOTE: menuitem's close tag should be omitted, but that causes problems. }; // For HTML, certain tags cannot have children. This has the same purpose as @@ -703,24 +926,31 @@ var voidElementTags = _assign({ menuitem: true }, omittedCloseTags); +// TODO: We can remove this if we add invariantWithStack() +// or add stack by default to invariants where possible. var HTML = '__html'; -function assertValidProps(tag, props, getStack) { +var ReactDebugCurrentFrame$2 = null; +{ + ReactDebugCurrentFrame$2 = ReactSharedInternals.ReactDebugCurrentFrame; +} + +function assertValidProps(tag, props) { if (!props) { return; } // Note the use of `==` which checks for null or undefined. if (voidElementTags[tag]) { - !(props.children == null && props.dangerouslySetInnerHTML == null) ? invariant(false, '%s is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`.%s', tag, getStack()) : void 0; + !(props.children == null && props.dangerouslySetInnerHTML == null) ? invariant(false, '%s is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`.%s', tag, ReactDebugCurrentFrame$2.getStackAddendum()) : void 0; } if (props.dangerouslySetInnerHTML != null) { !(props.children == null) ? invariant(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : void 0; !(typeof props.dangerouslySetInnerHTML === 'object' && HTML in props.dangerouslySetInnerHTML) ? invariant(false, '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. Please visit https://fb.me/react-invariant-dangerously-set-inner-html for more information.') : void 0; } { - warning(props.suppressContentEditableWarning || !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.%s', getStack()); + !(props.suppressContentEditableWarning || !props.contentEditable || props.children == null) ? warning$1(false, '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.') : void 0; } - !(props.style == null || typeof props.style === 'object') ? 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', getStack()) : void 0; + !(props.style == null || typeof props.style === 'object') ? 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', ReactDebugCurrentFrame$2.getStackAddendum()) : void 0; } /** @@ -742,6 +972,7 @@ var isUnitlessNumber = { flexShrink: true, flexNegative: true, flexOrder: true, + gridArea: true, gridRow: true, gridRowEnd: true, gridRowSpan: true, @@ -828,6 +1059,26 @@ function dangerousStyleValue(name, value, isCustomProperty) { return ('' + value).trim(); } +var uppercasePattern = /([A-Z])/g; +var msPattern = /^ms-/; + +/** + * Hyphenates a camelcased CSS property name, for example: + * + * > hyphenateStyleName('backgroundColor') + * < "background-color" + * > hyphenateStyleName('MozTransition') + * < "-moz-transition" + * > hyphenateStyleName('msTransition') + * < "-ms-transition" + * + * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix + * is converted to `-ms-`. + */ +function hyphenateStyleName(name) { + return name.replace(uppercasePattern, '-$1').toLowerCase().replace(msPattern, '-ms-'); +} + function isCustomComponent(tagName, props) { if (tagName.indexOf('-') === -1) { return typeof props.is === 'string'; @@ -851,11 +1102,13 @@ function isCustomComponent(tagName, props) { } } -var warnValidStyle = emptyFunction; +var warnValidStyle = function () {}; { // 'msTransform' is correct, but the other prefixes should be capitalized var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/; + var msPattern$1 = /^-ms-/; + var hyphenPattern = /-(.)/g; // style values shouldn't contain a semicolon var badStyleValueWithSemicolonPattern = /;\s*$/; @@ -865,65 +1118,75 @@ var warnValidStyle = emptyFunction; var warnedForNaNValue = false; var warnedForInfinityValue = false; - var warnHyphenatedStyleName = function (name, getStack) { + var camelize = function (string) { + return string.replace(hyphenPattern, function (_, character) { + return character.toUpperCase(); + }); + }; + + var warnHyphenatedStyleName = function (name) { if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { return; } warnedStyleNames[name] = true; - warning(false, 'Unsupported style property %s. Did you mean %s?%s', name, camelizeStyleName(name), getStack()); + warning$1(false, 'Unsupported style property %s. Did you mean %s?', name, + // As Andi Smith suggests + // (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix + // is converted to lowercase `ms`. + camelize(name.replace(msPattern$1, 'ms-'))); }; - var warnBadVendoredStyleName = function (name, getStack) { + var warnBadVendoredStyleName = function (name) { if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { return; } warnedStyleNames[name] = true; - warning(false, 'Unsupported vendor-prefixed style property %s. Did you mean %s?%s', name, name.charAt(0).toUpperCase() + name.slice(1), getStack()); + warning$1(false, 'Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1)); }; - var warnStyleValueWithSemicolon = function (name, value, getStack) { + var warnStyleValueWithSemicolon = function (name, value) { if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) { return; } warnedStyleValues[value] = true; - warning(false, "Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.%s', name, value.replace(badStyleValueWithSemicolonPattern, ''), getStack()); + warning$1(false, "Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.', name, value.replace(badStyleValueWithSemicolonPattern, '')); }; - var warnStyleValueIsNaN = function (name, value, getStack) { + var warnStyleValueIsNaN = function (name, value) { if (warnedForNaNValue) { return; } warnedForNaNValue = true; - warning(false, '`NaN` is an invalid value for the `%s` css style property.%s', name, getStack()); + warning$1(false, '`NaN` is an invalid value for the `%s` css style property.', name); }; - var warnStyleValueIsInfinity = function (name, value, getStack) { + var warnStyleValueIsInfinity = function (name, value) { if (warnedForInfinityValue) { return; } warnedForInfinityValue = true; - warning(false, '`Infinity` is an invalid value for the `%s` css style property.%s', name, getStack()); + warning$1(false, '`Infinity` is an invalid value for the `%s` css style property.', name); }; - warnValidStyle = function (name, value, getStack) { + warnValidStyle = function (name, value) { if (name.indexOf('-') > -1) { - warnHyphenatedStyleName(name, getStack); + warnHyphenatedStyleName(name); } else if (badVendoredStyleNamePattern.test(name)) { - warnBadVendoredStyleName(name, getStack); + warnBadVendoredStyleName(name); } else if (badStyleValueWithSemicolonPattern.test(value)) { - warnStyleValueWithSemicolon(name, value, getStack); + warnStyleValueWithSemicolon(name, value); } if (typeof value === 'number') { if (isNaN(value)) { - warnStyleValueIsNaN(name, value, getStack); + warnStyleValueIsNaN(name, value); } else if (!isFinite(value)) { - warnStyleValueIsInfinity(name, value, getStack); + warnStyleValueIsInfinity(name, value); } } }; @@ -990,15 +1253,10 @@ var warnedProperties = {}; var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$'); var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$'); -var hasOwnProperty = Object.prototype.hasOwnProperty; - -function getStackAddendum$1() { - var stack = ReactDebugCurrentFrame.getStackAddendum(); - return stack != null ? stack : ''; -} +var hasOwnProperty$2 = Object.prototype.hasOwnProperty; function validateProperty(tagName, name) { - if (hasOwnProperty.call(warnedProperties, name) && warnedProperties[name]) { + if (hasOwnProperty$2.call(warnedProperties, name) && warnedProperties[name]) { return true; } @@ -1009,13 +1267,13 @@ function validateProperty(tagName, name) { // If this is an aria-* attribute, but is not listed in the known DOM // DOM properties, then it is an invalid aria-* attribute. if (correctName == null) { - warning(false, 'Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.%s', name, getStackAddendum$1()); + warning$1(false, 'Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.', name); warnedProperties[name] = true; return true; } // aria-* attributes should be lowercase; suggest the lowercase version. if (name !== correctName) { - warning(false, 'Invalid ARIA attribute `%s`. Did you mean `%s`?%s', name, correctName, getStackAddendum$1()); + warning$1(false, 'Invalid ARIA attribute `%s`. Did you mean `%s`?', name, correctName); warnedProperties[name] = true; return true; } @@ -1033,7 +1291,7 @@ function validateProperty(tagName, name) { } // aria-* attributes should be lowercase; suggest the lowercase version. if (name !== standardName) { - warning(false, 'Unknown ARIA attribute `%s`. Did you mean `%s`?%s', name, standardName, getStackAddendum$1()); + warning$1(false, 'Unknown ARIA attribute `%s`. Did you mean `%s`?', name, standardName); warnedProperties[name] = true; return true; } @@ -1057,9 +1315,9 @@ function warnInvalidARIAProps(type, props) { }).join(', '); if (invalidProps.length === 1) { - warning(false, 'Invalid aria prop %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop%s', unknownPropString, type, getStackAddendum$1()); + warning$1(false, 'Invalid aria prop %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type); } else if (invalidProps.length > 1) { - warning(false, 'Invalid aria props %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop%s', unknownPropString, type, getStackAddendum$1()); + warning$1(false, 'Invalid aria props %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type); } } @@ -1072,11 +1330,6 @@ function validateProperties(type, props) { var didWarnValueNull = false; -function getStackAddendum$2() { - var stack = ReactDebugCurrentFrame.getStackAddendum(); - return stack != null ? stack : ''; -} - function validateProperties$1(type, props) { if (type !== 'input' && type !== 'textarea' && type !== 'select') { return; @@ -1085,9 +1338,9 @@ function validateProperties$1(type, props) { if (props != null && props.value === null && !didWarnValueNull) { didWarnValueNull = true; if (type === 'select' && props.multiple) { - warning(false, '`value` prop on `%s` should not be null. ' + 'Consider using an empty array when `multiple` is set to `true` ' + 'to clear the component or `undefined` for uncontrolled components.%s', type, getStackAddendum$2()); + warning$1(false, '`value` prop on `%s` should not be null. ' + 'Consider using an empty array when `multiple` is set to `true` ' + 'to clear the component or `undefined` for uncontrolled components.', type); } else { - warning(false, '`value` prop on `%s` should not be null. ' + 'Consider using an empty string to clear the component or `undefined` ' + 'for uncontrolled components.%s', type, getStackAddendum$2()); + warning$1(false, '`value` prop on `%s` should not be null. ' + 'Consider using an empty string to clear the component or `undefined` ' + 'for uncontrolled components.', type); } } } @@ -1177,7 +1430,7 @@ var possibleStandardNames = { checked: 'checked', children: 'children', cite: 'cite', - 'class': 'className', + class: 'className', classid: 'classID', classname: 'className', cols: 'cols', @@ -1192,7 +1445,7 @@ var possibleStandardNames = { dangerouslysetinnerhtml: 'dangerouslySetInnerHTML', data: 'data', datetime: 'dateTime', - 'default': 'default', + default: 'default', defaultchecked: 'defaultChecked', defaultvalue: 'defaultValue', defer: 'defer', @@ -1201,7 +1454,7 @@ var possibleStandardNames = { download: 'download', draggable: 'draggable', enctype: 'encType', - 'for': 'htmlFor', + for: 'htmlFor', form: 'form', formmethod: 'formMethod', formaction: 'formAction', @@ -1250,6 +1503,7 @@ var possibleStandardNames = { multiple: 'multiple', muted: 'muted', name: 'name', + nomodule: 'noModule', nonce: 'nonce', novalidate: 'noValidate', open: 'open', @@ -1418,7 +1672,7 @@ var possibleStandardNames = { imagerendering: 'imageRendering', 'image-rendering': 'imageRendering', in2: 'in2', - 'in': 'in', + in: 'in', inlist: 'inlist', intercept: 'intercept', k1: 'k1', @@ -1558,7 +1812,7 @@ var possibleStandardNames = { 'text-rendering': 'textRendering', to: 'to', transform: 'transform', - 'typeof': 'typeof', + typeof: 'typeof', u1: 'u1', u2: 'u2', underlineposition: 'underlinePosition', @@ -1637,27 +1891,24 @@ var possibleStandardNames = { zoomandpan: 'zoomAndPan' }; -function getStackAddendum$3() { - var stack = ReactDebugCurrentFrame.getStackAddendum(); - return stack != null ? stack : ''; -} +var validateProperty$1 = function () {}; { var warnedProperties$1 = {}; - var hasOwnProperty$1 = Object.prototype.hasOwnProperty; + var _hasOwnProperty = Object.prototype.hasOwnProperty; var EVENT_NAME_REGEX = /^on./; var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/; var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$'); var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$'); - var validateProperty$1 = function (tagName, name, value, canUseEventSystem) { - if (hasOwnProperty$1.call(warnedProperties$1, name) && warnedProperties$1[name]) { + validateProperty$1 = function (tagName, name, value, canUseEventSystem) { + if (_hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) { return true; } var lowerCasedName = name.toLowerCase(); if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') { - warning(false, 'React uses onFocus and onBlur instead of onFocusIn and onFocusOut. ' + 'All React events are normalized to bubble, so onFocusIn and onFocusOut ' + 'are not needed/supported by React.'); + warning$1(false, 'React uses onFocus and onBlur instead of onFocusIn and onFocusOut. ' + 'All React events are normalized to bubble, so onFocusIn and onFocusOut ' + 'are not needed/supported by React.'); warnedProperties$1[name] = true; return true; } @@ -1669,12 +1920,12 @@ function getStackAddendum$3() { } var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null; if (registrationName != null) { - warning(false, 'Invalid event handler property `%s`. Did you mean `%s`?%s', name, registrationName, getStackAddendum$3()); + warning$1(false, 'Invalid event handler property `%s`. Did you mean `%s`?', name, registrationName); warnedProperties$1[name] = true; return true; } if (EVENT_NAME_REGEX.test(name)) { - warning(false, 'Unknown event handler property `%s`. It will be ignored.%s', name, getStackAddendum$3()); + warning$1(false, 'Unknown event handler property `%s`. It will be ignored.', name); warnedProperties$1[name] = true; return true; } @@ -1683,7 +1934,7 @@ function getStackAddendum$3() { // So we can't tell if the event name is correct for sure, but we can filter // out known bad ones like `onclick`. We can't suggest a specific replacement though. if (INVALID_EVENT_NAME_REGEX.test(name)) { - warning(false, 'Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.%s', name, getStackAddendum$3()); + warning$1(false, 'Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.', name); } warnedProperties$1[name] = true; return true; @@ -1695,52 +1946,53 @@ function getStackAddendum$3() { } if (lowerCasedName === 'innerhtml') { - warning(false, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.'); + warning$1(false, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.'); warnedProperties$1[name] = true; return true; } if (lowerCasedName === 'aria') { - warning(false, 'The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.'); + warning$1(false, 'The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.'); warnedProperties$1[name] = true; return true; } if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') { - warning(false, 'Received a `%s` for a string attribute `is`. If this is expected, cast ' + 'the value to a string.%s', typeof value, getStackAddendum$3()); + warning$1(false, 'Received a `%s` for a string attribute `is`. If this is expected, cast ' + 'the value to a string.', typeof value); warnedProperties$1[name] = true; return true; } if (typeof value === 'number' && isNaN(value)) { - warning(false, 'Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.%s', name, getStackAddendum$3()); + warning$1(false, 'Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.', name); warnedProperties$1[name] = true; return true; } - var isReserved = isReservedProp(name); + var propertyInfo = getPropertyInfo(name); + var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED; // Known attributes should match the casing specified in the property config. if (possibleStandardNames.hasOwnProperty(lowerCasedName)) { var standardName = possibleStandardNames[lowerCasedName]; if (standardName !== name) { - warning(false, 'Invalid DOM property `%s`. Did you mean `%s`?%s', name, standardName, getStackAddendum$3()); + warning$1(false, 'Invalid DOM property `%s`. Did you mean `%s`?', name, standardName); warnedProperties$1[name] = true; return true; } } else if (!isReserved && name !== lowerCasedName) { // Unknown attributes should have lowercase casing since that's how they // will be cased anyway with server rendering. - warning(false, 'React does not recognize the `%s` prop on a DOM element. If you ' + 'intentionally want it to appear in the DOM as a custom ' + 'attribute, spell it as lowercase `%s` instead. ' + 'If you accidentally passed it from a parent component, remove ' + 'it from the DOM element.%s', name, lowerCasedName, getStackAddendum$3()); + warning$1(false, 'React does not recognize the `%s` prop on a DOM element. If you ' + 'intentionally want it to appear in the DOM as a custom ' + 'attribute, spell it as lowercase `%s` instead. ' + 'If you accidentally passed it from a parent component, remove ' + 'it from the DOM element.', name, lowerCasedName); warnedProperties$1[name] = true; return true; } - if (typeof value === 'boolean' && !shouldAttributeAcceptBooleanValue(name)) { + if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) { if (value) { - warning(false, 'Received `%s` for a non-boolean attribute `%s`.\n\n' + 'If you want to write it to the DOM, pass a string instead: ' + '%s="%s" or %s={value.toString()}.%s', value, name, name, value, name, getStackAddendum$3()); + warning$1(false, 'Received `%s` for a non-boolean attribute `%s`.\n\n' + 'If you want to write it to the DOM, pass a string instead: ' + '%s="%s" or %s={value.toString()}.', value, name, name, value, name); } else { - warning(false, 'Received `%s` for a non-boolean attribute `%s`.\n\n' + 'If you want to write it to the DOM, pass a string instead: ' + '%s="%s" or %s={value.toString()}.\n\n' + 'If you used to conditionally omit it with %s={condition && value}, ' + 'pass %s={condition ? value : undefined} instead.%s', value, name, name, value, name, name, name, getStackAddendum$3()); + warning$1(false, 'Received `%s` for a non-boolean attribute `%s`.\n\n' + 'If you want to write it to the DOM, pass a string instead: ' + '%s="%s" or %s={value.toString()}.\n\n' + 'If you used to conditionally omit it with %s={condition && value}, ' + 'pass %s={condition ? value : undefined} instead.', value, name, name, value, name, name, name); } warnedProperties$1[name] = true; return true; @@ -1753,11 +2005,18 @@ function getStackAddendum$3() { } // Warn when a known attribute is a bad type - if (!shouldSetAttribute(name, value)) { + if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) { warnedProperties$1[name] = true; return false; } + // Warn when passing the strings 'false' or 'true' into a boolean prop + if ((value === 'false' || value === 'true') && propertyInfo !== null && propertyInfo.type === BOOLEAN) { + warning$1(false, 'Received the string `%s` for the boolean attribute `%s`. ' + '%s ' + 'Did you mean %s={%s}?', value, name, value === 'false' ? 'The browser will interpret it as a truthy value.' : 'Although this works, it will not work as expected if you pass the string "false".', name, value); + warnedProperties$1[name] = true; + return true; + } + return true; }; } @@ -1775,9 +2034,9 @@ var warnUnknownProperties = function (type, props, canUseEventSystem) { return '`' + prop + '`'; }).join(', '); if (unknownProps.length === 1) { - warning(false, 'Invalid value for prop %s on <%s> tag. Either remove it from the element, ' + 'or pass a string or number value to keep it in the DOM. ' + 'For details, see https://fb.me/react-attribute-behavior%s', unknownPropString, type, getStackAddendum$3()); + warning$1(false, 'Invalid value for prop %s on <%s> tag. Either remove it from the element, ' + 'or pass a string or number value to keep it in the DOM. ' + 'For details, see https://fb.me/react-attribute-behavior', unknownPropString, type); } else if (unknownProps.length > 1) { - warning(false, 'Invalid values for props %s on <%s> tag. Either remove them from the element, ' + 'or pass a string or number value to keep them in the DOM. ' + 'For details, see https://fb.me/react-attribute-behavior%s', unknownPropString, type, getStackAddendum$3()); + warning$1(false, 'Invalid values for props %s on <%s> tag. Either remove them from the element, ' + 'or pass a string or number value to keep them in the DOM. ' + 'For details, see https://fb.me/react-attribute-behavior', unknownPropString, type); } }; @@ -1794,16 +2053,36 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons var toArray = React.Children.toArray; -var getStackAddendum = emptyFunction.thatReturns(''); +// This is only used in DEV. +// Each entry is `this.stack` from a currently executing renderer instance. +// (There may be more than one because ReactDOMServer is reentrant). +// Each stack is an array of frames which may contain nested stacks of elements. +var currentDebugStacks = []; + +var ReactDebugCurrentFrame = void 0; +var prevGetCurrentStackImpl = null; +var getCurrentServerStackImpl = function () { + return ''; +}; +var describeStackFrame = function (element) { + return ''; +}; + +var validatePropertiesInDevelopment = function (type, props) {}; +var pushCurrentDebugStack = function (stack) {}; +var pushElementToDebugStack = function (element) {}; +var popCurrentDebugStack = function () {}; { - var validatePropertiesInDevelopment = function (type, props) { + ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + + validatePropertiesInDevelopment = function (type, props) { validateProperties(type, props); validateProperties$1(type, props); validateProperties$2(type, props, /* canUseEventSystem */false); }; - var describeStackFrame = function (element) { + describeStackFrame = function (element) { var source = element._source; var type = element.type; var name = getComponentName(type); @@ -1811,34 +2090,55 @@ var getStackAddendum = emptyFunction.thatReturns(''); return describeComponentFrame(name, source, ownerName); }; - var currentDebugStack = null; - var currentDebugElementStack = null; - var setCurrentDebugStack = function (stack) { + pushCurrentDebugStack = function (stack) { + currentDebugStacks.push(stack); + + if (currentDebugStacks.length === 1) { + // We are entering a server renderer. + // Remember the previous (e.g. client) global stack implementation. + prevGetCurrentStackImpl = ReactDebugCurrentFrame.getCurrentStack; + ReactDebugCurrentFrame.getCurrentStack = getCurrentServerStackImpl; + } + }; + + pushElementToDebugStack = function (element) { + // For the innermost executing ReactDOMServer call, + var stack = currentDebugStacks[currentDebugStacks.length - 1]; + // Take the innermost executing frame (e.g. ), var frame = stack[stack.length - 1]; - currentDebugElementStack = frame.debugElementStack; - // We are about to enter a new composite stack, reset the array. - currentDebugElementStack.length = 0; - currentDebugStack = stack; - ReactDebugCurrentFrame.getCurrentStack = getStackAddendum; + // and record that it has one more element associated with it. + frame.debugElementStack.push(element); + // We only need this because we tail-optimize single-element + // children and directly handle them in an inner loop instead of + // creating separate frames for them. }; - var pushElementToDebugStack = function (element) { - if (currentDebugElementStack !== null) { - currentDebugElementStack.push(element); + + popCurrentDebugStack = function () { + currentDebugStacks.pop(); + + if (currentDebugStacks.length === 0) { + // We are exiting the server renderer. + // Restore the previous (e.g. client) global stack implementation. + ReactDebugCurrentFrame.getCurrentStack = prevGetCurrentStackImpl; + prevGetCurrentStackImpl = null; } }; - var resetCurrentDebugStack = function () { - currentDebugElementStack = null; - currentDebugStack = null; - ReactDebugCurrentFrame.getCurrentStack = null; - }; - getStackAddendum = function () { - if (currentDebugStack === null) { + + getCurrentServerStackImpl = function () { + if (currentDebugStacks.length === 0) { + // Nothing is currently rendering. return ''; } + // ReactDOMServer is reentrant so there may be multiple calls at the same time. + // Take the frames from the innermost call which is the last in the array. + var frames = currentDebugStacks[currentDebugStacks.length - 1]; var stack = ''; - var debugStack = currentDebugStack; - for (var i = debugStack.length - 1; i >= 0; i--) { - var frame = debugStack[i]; + // Go through every frame in the stack from the innermost one. + for (var i = frames.length - 1; i >= 0; i--) { + var frame = frames[i]; + // Every frame might have more than one debug element stack entry associated with it. + // This is because single-child nesting doesn't create materialized frames. + // Instead it would push them through `pushElementToDebugStack()`. var _debugElementStack = frame.debugElementStack; for (var ii = _debugElementStack.length - 1; ii >= 0; ii--) { stack += describeStackFrame(_debugElementStack[ii]); @@ -1854,6 +2154,10 @@ var didWarnDefaultSelectValue = false; var didWarnDefaultTextareaValue = false; var didWarnInvalidOptionChildren = false; var didWarnAboutNoopUpdateForComponent = {}; +var didWarnAboutBadClass = {}; +var didWarnAboutDeprecatedWillMount = {}; +var didWarnAboutUndefinedDerivedState = {}; +var didWarnAboutUninitializedState = {}; var valuePropNames = ['value', 'defaultValue']; var newlineEatingTags = { listing: true, @@ -1861,10 +2165,6 @@ var newlineEatingTags = { textarea: true }; -function getComponentName(type) { - return typeof type === 'string' ? type : typeof type === 'function' ? type.displayName || type.name : null; -} - // We accept any tag to be rendered but since this gets injected into arbitrary // HTML, we want to make sure that it's a safe tag. // http://www.w3.org/TR/REC-xml/#NT-Name @@ -1877,9 +2177,15 @@ function validateDangerousTag(tag) { } } -var processStyleName = memoizeStringOnly(function (styleName) { - return hyphenateStyleName(styleName); -}); +var styleNameCache = {}; +var processStyleName = function (styleName) { + if (styleNameCache.hasOwnProperty(styleName)) { + return styleNameCache[styleName]; + } + var result = hyphenateStyleName(styleName); + styleNameCache[styleName] = result; + return result; +}; function createMarkupForStyles(styles) { var serialized = ''; @@ -1892,7 +2198,7 @@ function createMarkupForStyles(styles) { var styleValue = styles[styleName]; { if (!isCustomProperty) { - warnValidStyle$1(styleName, styleValue, getStackAddendum); + warnValidStyle$1(styleName, styleValue); } } if (styleValue != null) { @@ -1907,14 +2213,14 @@ function createMarkupForStyles(styles) { function warnNoop(publicInstance, callerName) { { - var constructor = publicInstance.constructor; - var componentName = constructor && getComponentName(constructor) || 'ReactClass'; + var _constructor = publicInstance.constructor; + var componentName = _constructor && getComponentName(_constructor) || 'ReactClass'; var warningKey = componentName + '.' + callerName; if (didWarnAboutNoopUpdateForComponent[warningKey]) { return; } - warning(false, '%s(...): Can only update a mounting component. ' + 'This usually means you called %s() outside componentWillMount() on the server. ' + 'This is a no-op.\n\nPlease check the code for the %s component.', callerName, callerName, componentName); + warningWithoutStack$1(false, '%s(...): Can only update a mounting component. ' + 'This usually means you called %s() outside componentWillMount() on the server. ' + 'This is a no-op.\n\nPlease check the code for the %s component.', callerName, callerName, componentName); didWarnAboutNoopUpdateForComponent[warningKey] = true; } } @@ -1955,6 +2261,9 @@ function flattenTopLevelChildren(children) { } function flattenOptionChildren(children) { + if (children === undefined || children === null) { + return children; + } var content = ''; // Flatten children and warn if they aren't strings or numbers; // invalid types are ignored. @@ -1962,20 +2271,22 @@ function flattenOptionChildren(children) { if (child == null) { return; } - if (typeof child === 'string' || typeof child === 'number') { - content += child; - } else { - { - if (!didWarnInvalidOptionChildren) { - didWarnInvalidOptionChildren = true; - warning(false, 'Only strings and numbers are supported as