react-dom
Version:
React package for working with the DOM.
1,467 lines (1,307 loc) • 244 kB
JavaScript
/**
* @license React
* react-dom-server-legacy.browser.development.js
*
* 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.
*/
'use strict';
if (process.env.NODE_ENV !== "production") {
(function() {
'use strict';
var React = require('react');
var ReactVersion = '18.3.1';
var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
// by calls to these methods by a Babel plugin.
//
// In PROD (or in packages without access to React internals),
// they are left as they are instead.
function warn(format) {
{
{
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
printWarning('warn', format, args);
}
}
}
function error(format) {
{
{
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
args[_key2 - 1] = arguments[_key2];
}
printWarning('error', format, args);
}
}
}
function printWarning(level, format, args) {
// When changing this logic, you might want to also
// update consoleWithStackDev.www.js as well.
{
var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
var stack = ReactDebugCurrentFrame.getStackAddendum();
if (stack !== '') {
format += '%s';
args = args.concat([stack]);
} // eslint-disable-next-line react-internal/safe-string-coercion
var argsWithFormat = args.map(function (item) {
return String(item);
}); // Careful: RN currently depends on this prefix
argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
// breaks IE9: https://github.com/facebook/react/issues/13610
// eslint-disable-next-line react-internal/no-production-logging
Function.prototype.apply.call(console[level], console, argsWithFormat);
}
}
function scheduleWork(callback) {
callback();
}
function beginWriting(destination) {}
function writeChunk(destination, chunk) {
writeChunkAndReturn(destination, chunk);
}
function writeChunkAndReturn(destination, chunk) {
return destination.push(chunk);
}
function completeWriting(destination) {}
function close(destination) {
destination.push(null);
}
function stringToChunk(content) {
return content;
}
function stringToPrecomputedChunk(content) {
return content;
}
function closeWithError(destination, error) {
// $FlowFixMe: This is an Error object or the destination accepts other types.
destination.destroy(error);
}
/*
* The `'' + value` pattern (used in in perf-sensitive code) throws for Symbol
* and Temporal.* types. See https://github.com/facebook/react/pull/22064.
*
* The functions in this module will throw an easier-to-understand,
* easier-to-debug exception with a clear errors message message explaining the
* problem. (Instead of a confusing exception thrown inside the implementation
* of the `value` object).
*/
// $FlowFixMe only called in DEV, so void return is not possible.
function typeName(value) {
{
// toStringTag is needed for namespaced types like Temporal.Instant
var hasToStringTag = typeof Symbol === 'function' && Symbol.toStringTag;
var type = hasToStringTag && value[Symbol.toStringTag] || value.constructor.name || 'Object';
return type;
}
} // $FlowFixMe only called in DEV, so void return is not possible.
function willCoercionThrow(value) {
{
try {
testStringCoercion(value);
return false;
} catch (e) {
return true;
}
}
}
function testStringCoercion(value) {
// If you ended up here by following an exception call stack, here's what's
// happened: you supplied an object or symbol value to React (as a prop, key,
// DOM attribute, CSS property, string ref, etc.) and when React tried to
// coerce it to a string using `'' + value`, an exception was thrown.
//
// The most common types that will cause this exception are `Symbol` instances
// and Temporal objects like `Temporal.Instant`. But any object that has a
// `valueOf` or `[Symbol.toPrimitive]` method that throws will also cause this
// exception. (Library authors do this to prevent users from using built-in
// numeric operators like `+` or comparison operators like `>=` because custom
// methods are needed to perform accurate arithmetic or comparison.)
//
// To fix the problem, coerce this object or symbol value to a string before
// passing it to React. The most reliable way is usually `String(value)`.
//
// To find which value is throwing, check the browser or debugger console.
// Before this exception was thrown, there should be `console.error` output
// that shows the type (Symbol, Temporal.PlainDate, etc.) that caused the
// problem and how that type was used: key, atrribute, input value prop, etc.
// In most cases, this console output also shows the component and its
// ancestor components where the exception happened.
//
// eslint-disable-next-line react-internal/safe-string-coercion
return '' + value;
}
function checkAttributeStringCoercion(value, attributeName) {
{
if (willCoercionThrow(value)) {
error('The provided `%s` attribute is an unsupported type %s.' + ' This value must be coerced to a string before before using it here.', attributeName, typeName(value));
return testStringCoercion(value); // throw (to help callers find troubleshooting comments)
}
}
}
function checkCSSPropertyStringCoercion(value, propName) {
{
if (willCoercionThrow(value)) {
error('The provided `%s` CSS property is an unsupported type %s.' + ' This value must be coerced to a string before before using it here.', propName, typeName(value));
return testStringCoercion(value); // throw (to help callers find troubleshooting comments)
}
}
}
function checkHtmlStringCoercion(value) {
{
if (willCoercionThrow(value)) {
error('The provided HTML markup uses a value of unsupported type %s.' + ' This value must be coerced to a string before before using it here.', typeName(value));
return testStringCoercion(value); // throw (to help callers find troubleshooting comments)
}
}
}
var hasOwnProperty = Object.prototype.hasOwnProperty;
// 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 filter 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";
/* eslint-enable max-len */
var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + "\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$');
var illegalAttributeNameCache = {};
var validatedAttributeNameCache = {};
function isAttributeNameSafe(attributeName) {
if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) {
return true;
}
if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) {
return false;
}
if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {
validatedAttributeNameCache[attributeName] = true;
return true;
}
illegalAttributeNameCache[attributeName] = true;
{
error('Invalid attribute name: `%s`', attributeName);
}
return false;
}
function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) {
if (propertyInfo !== null && propertyInfo.type === RESERVED) {
return false;
}
switch (typeof value) {
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:
return false;
}
}
function getPropertyInfo(name) {
return properties.hasOwnProperty(name) ? properties[name] : null;
}
function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace, sanitizeURL, removeEmptyString) {
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;
this.sanitizeURL = sanitizeURL;
this.removeEmptyString = removeEmptyString;
} // 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 = {}; // These props are reserved by React. They shouldn't be written to the DOM.
var reservedProps = ['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'];
reservedProps.forEach(function (name) {
properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty
name, // attributeName
null, // attributeNamespace
false, // sanitizeURL
false);
}); // 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
false, // sanitizeURL
false);
}); // 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
false, // sanitizeURL
false);
}); // 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
false, // sanitizeURL
false);
}); // 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', 'disablePictureInPicture', 'disableRemotePlayback', '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
false, // sanitizeURL
false);
}); // 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' // NOTE: if you add a camelCased prop to this list,
// you'll need to set attributeName to name.toLowerCase()
// instead in the assignment below.
].forEach(function (name) {
properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty
name, // attributeName
null, // attributeNamespace
false, // sanitizeURL
false);
}); // These are HTML attributes that are "overloaded booleans": they behave like
// booleans, but can also accept a string value.
['capture', 'download' // NOTE: if you add a camelCased prop to this list,
// you'll need to set attributeName to name.toLowerCase()
// instead in the assignment below.
].forEach(function (name) {
properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty
name, // attributeName
null, // attributeNamespace
false, // sanitizeURL
false);
}); // These are HTML attributes that must be positive numbers.
['cols', 'rows', 'size', 'span' // NOTE: if you add a camelCased prop to this list,
// you'll need to set attributeName to name.toLowerCase()
// instead in the assignment below.
].forEach(function (name) {
properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty
name, // attributeName
null, // attributeNamespace
false, // sanitizeURL
false);
}); // 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
false, // sanitizeURL
false);
});
var CAMELIZE = /[\-\:]([a-z])/g;
var capitalize = function (token) {
return token[1].toUpperCase();
}; // 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 attribute filter.
// Some of these attributes can be hard to find. This list was created by
// scraping 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' // NOTE: if you add a camelCased prop to this list,
// you'll need to set attributeName to name.toLowerCase()
// instead in the assignment below.
].forEach(function (attributeName) {
var name = attributeName.replace(CAMELIZE, capitalize);
properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
attributeName, null, // attributeNamespace
false, // sanitizeURL
false);
}); // String SVG attributes with the xlink namespace.
['xlink:actuate', 'xlink:arcrole', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type' // NOTE: if you add a camelCased prop to this list,
// you'll need to set attributeName to name.toLowerCase()
// instead in the assignment below.
].forEach(function (attributeName) {
var name = attributeName.replace(CAMELIZE, capitalize);
properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
attributeName, 'http://www.w3.org/1999/xlink', false, // sanitizeURL
false);
}); // String SVG attributes with the xml namespace.
['xml:base', 'xml:lang', 'xml:space' // NOTE: if you add a camelCased prop to this list,
// you'll need to set attributeName to name.toLowerCase()
// instead in the assignment below.
].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', false, // sanitizeURL
false);
}); // These attribute exists both in HTML and SVG.
// The attribute name is case-sensitive in SVG so we can't just use
// the React name like we do for attributes that exist only in HTML.
['tabIndex', 'crossOrigin'].forEach(function (attributeName) {
properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
attributeName.toLowerCase(), // attributeName
null, // attributeNamespace
false, // sanitizeURL
false);
}); // These attributes accept URLs. These must not allow javascript: URLS.
// These will also need to accept Trusted Types object in the future.
var xlinkHref = 'xlinkHref';
properties[xlinkHref] = new PropertyInfoRecord('xlinkHref', STRING, false, // mustUseProperty
'xlink:href', 'http://www.w3.org/1999/xlink', true, // sanitizeURL
false);
['src', 'href', 'action', 'formAction'].forEach(function (attributeName) {
properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
attributeName.toLowerCase(), // attributeName
null, // attributeNamespace
true, // sanitizeURL
true);
});
/**
* CSS properties which accept numbers but are not in units of "px".
*/
var isUnitlessNumber = {
animationIterationCount: true,
aspectRatio: true,
borderImageOutset: true,
borderImageSlice: true,
borderImageWidth: true,
boxFlex: true,
boxFlexGroup: true,
boxOrdinalGroup: true,
columnCount: true,
columns: true,
flex: true,
flexGrow: true,
flexPositive: true,
flexShrink: true,
flexNegative: true,
flexOrder: true,
gridArea: true,
gridRow: true,
gridRowEnd: true,
gridRowSpan: true,
gridRowStart: true,
gridColumn: true,
gridColumnEnd: true,
gridColumnSpan: true,
gridColumnStart: true,
fontWeight: true,
lineClamp: true,
lineHeight: true,
opacity: true,
order: true,
orphans: true,
tabSize: true,
widows: true,
zIndex: true,
zoom: true,
// SVG-related properties
fillOpacity: true,
floodOpacity: true,
stopOpacity: true,
strokeDasharray: true,
strokeDashoffset: true,
strokeMiterlimit: true,
strokeOpacity: true,
strokeWidth: true
};
/**
* @param {string} prefix vendor-specific prefix, eg: Webkit
* @param {string} key style name, eg: transitionDuration
* @return {string} style name prefixed with `prefix`, properly camelCased, eg:
* WebkitTransitionDuration
*/
function prefixKey(prefix, key) {
return prefix + key.charAt(0).toUpperCase() + key.substring(1);
}
/**
* Support style names that may come passed in prefixed by adding permutations
* of vendor prefixes.
*/
var prefixes = ['Webkit', 'ms', 'Moz', 'O']; // Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
// infinite loop, because it iterates over the newly added props too.
Object.keys(isUnitlessNumber).forEach(function (prop) {
prefixes.forEach(function (prefix) {
isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
});
});
var hasReadOnlyValue = {
button: true,
checkbox: true,
image: true,
hidden: true,
radio: true,
reset: true,
submit: true
};
function checkControlledValueProps(tagName, props) {
{
if (!(hasReadOnlyValue[props.type] || props.onChange || props.onInput || props.readOnly || props.disabled || props.value == null)) {
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`.');
}
if (!(props.onChange || props.readOnly || props.disabled || props.checked == null)) {
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`.');
}
}
}
function isCustomComponent(tagName, props) {
if (tagName.indexOf('-') === -1) {
return typeof props.is === 'string';
}
switch (tagName) {
// These are reserved SVG and MathML elements.
// We don't mind this list too much because we expect it to never grow.
// The alternative is to track the namespace in a few places which is convoluted.
// https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts
case 'annotation-xml':
case 'color-profile':
case 'font-face':
case 'font-face-src':
case 'font-face-uri':
case 'font-face-format':
case 'font-face-name':
case 'missing-glyph':
return false;
default:
return true;
}
}
var ariaProperties = {
'aria-current': 0,
// state
'aria-description': 0,
'aria-details': 0,
'aria-disabled': 0,
// state
'aria-hidden': 0,
// state
'aria-invalid': 0,
// state
'aria-keyshortcuts': 0,
'aria-label': 0,
'aria-roledescription': 0,
// Widget Attributes
'aria-autocomplete': 0,
'aria-checked': 0,
'aria-expanded': 0,
'aria-haspopup': 0,
'aria-level': 0,
'aria-modal': 0,
'aria-multiline': 0,
'aria-multiselectable': 0,
'aria-orientation': 0,
'aria-placeholder': 0,
'aria-pressed': 0,
'aria-readonly': 0,
'aria-required': 0,
'aria-selected': 0,
'aria-sort': 0,
'aria-valuemax': 0,
'aria-valuemin': 0,
'aria-valuenow': 0,
'aria-valuetext': 0,
// Live Region Attributes
'aria-atomic': 0,
'aria-busy': 0,
'aria-live': 0,
'aria-relevant': 0,
// Drag-and-Drop Attributes
'aria-dropeffect': 0,
'aria-grabbed': 0,
// Relationship Attributes
'aria-activedescendant': 0,
'aria-colcount': 0,
'aria-colindex': 0,
'aria-colspan': 0,
'aria-controls': 0,
'aria-describedby': 0,
'aria-errormessage': 0,
'aria-flowto': 0,
'aria-labelledby': 0,
'aria-owns': 0,
'aria-posinset': 0,
'aria-rowcount': 0,
'aria-rowindex': 0,
'aria-rowspan': 0,
'aria-setsize': 0
};
var warnedProperties = {};
var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
function validateProperty(tagName, name) {
{
if (hasOwnProperty.call(warnedProperties, name) && warnedProperties[name]) {
return true;
}
if (rARIACamel.test(name)) {
var ariaName = 'aria-' + name.slice(4).toLowerCase();
var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null; // 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) {
error('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) {
error('Invalid ARIA attribute `%s`. Did you mean `%s`?', name, correctName);
warnedProperties[name] = true;
return true;
}
}
if (rARIA.test(name)) {
var lowerCasedName = name.toLowerCase();
var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null; // If this is an aria-* attribute, but is not listed in the known DOM
// DOM properties, then it is an invalid aria-* attribute.
if (standardName == null) {
warnedProperties[name] = true;
return false;
} // aria-* attributes should be lowercase; suggest the lowercase version.
if (name !== standardName) {
error('Unknown ARIA attribute `%s`. Did you mean `%s`?', name, standardName);
warnedProperties[name] = true;
return true;
}
}
}
return true;
}
function warnInvalidARIAProps(type, props) {
{
var invalidProps = [];
for (var key in props) {
var isValid = validateProperty(type, key);
if (!isValid) {
invalidProps.push(key);
}
}
var unknownPropString = invalidProps.map(function (prop) {
return '`' + prop + '`';
}).join(', ');
if (invalidProps.length === 1) {
error('Invalid aria prop %s on <%s> tag. ' + 'For details, see https://reactjs.org/link/invalid-aria-props', unknownPropString, type);
} else if (invalidProps.length > 1) {
error('Invalid aria props %s on <%s> tag. ' + 'For details, see https://reactjs.org/link/invalid-aria-props', unknownPropString, type);
}
}
}
function validateProperties(type, props) {
if (isCustomComponent(type, props)) {
return;
}
warnInvalidARIAProps(type, props);
}
var didWarnValueNull = false;
function validateProperties$1(type, props) {
{
if (type !== 'input' && type !== 'textarea' && type !== 'select') {
return;
}
if (props != null && props.value === null && !didWarnValueNull) {
didWarnValueNull = true;
if (type === 'select' && props.multiple) {
error('`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 {
error('`value` prop on `%s` should not be null. ' + 'Consider using an empty string to clear the component or `undefined` ' + 'for uncontrolled components.', type);
}
}
}
}
// When adding attributes to the HTML or SVG allowed attribute list, be sure to
// also add them to this module to ensure casing and incorrect name
// warnings.
var possibleStandardNames = {
// HTML
accept: 'accept',
acceptcharset: 'acceptCharset',
'accept-charset': 'acceptCharset',
accesskey: 'accessKey',
action: 'action',
allowfullscreen: 'allowFullScreen',
alt: 'alt',
as: 'as',
async: 'async',
autocapitalize: 'autoCapitalize',
autocomplete: 'autoComplete',
autocorrect: 'autoCorrect',
autofocus: 'autoFocus',
autoplay: 'autoPlay',
autosave: 'autoSave',
capture: 'capture',
cellpadding: 'cellPadding',
cellspacing: 'cellSpacing',
challenge: 'challenge',
charset: 'charSet',
checked: 'checked',
children: 'children',
cite: 'cite',
class: 'className',
classid: 'classID',
classname: 'className',
cols: 'cols',
colspan: 'colSpan',
content: 'content',
contenteditable: 'contentEditable',
contextmenu: 'contextMenu',
controls: 'controls',
controlslist: 'controlsList',
coords: 'coords',
crossorigin: 'crossOrigin',
dangerouslysetinnerhtml: 'dangerouslySetInnerHTML',
data: 'data',
datetime: 'dateTime',
default: 'default',
defaultchecked: 'defaultChecked',
defaultvalue: 'defaultValue',
defer: 'defer',
dir: 'dir',
disabled: 'disabled',
disablepictureinpicture: 'disablePictureInPicture',
disableremoteplayback: 'disableRemotePlayback',
download: 'download',
draggable: 'draggable',
enctype: 'encType',
enterkeyhint: 'enterKeyHint',
for: 'htmlFor',
form: 'form',
formmethod: 'formMethod',
formaction: 'formAction',
formenctype: 'formEncType',
formnovalidate: 'formNoValidate',
formtarget: 'formTarget',
frameborder: 'frameBorder',
headers: 'headers',
height: 'height',
hidden: 'hidden',
high: 'high',
href: 'href',
hreflang: 'hrefLang',
htmlfor: 'htmlFor',
httpequiv: 'httpEquiv',
'http-equiv': 'httpEquiv',
icon: 'icon',
id: 'id',
imagesizes: 'imageSizes',
imagesrcset: 'imageSrcSet',
innerhtml: 'innerHTML',
inputmode: 'inputMode',
integrity: 'integrity',
is: 'is',
itemid: 'itemID',
itemprop: 'itemProp',
itemref: 'itemRef',
itemscope: 'itemScope',
itemtype: 'itemType',
keyparams: 'keyParams',
keytype: 'keyType',
kind: 'kind',
label: 'label',
lang: 'lang',
list: 'list',
loop: 'loop',
low: 'low',
manifest: 'manifest',
marginwidth: 'marginWidth',
marginheight: 'marginHeight',
max: 'max',
maxlength: 'maxLength',
media: 'media',
mediagroup: 'mediaGroup',
method: 'method',
min: 'min',
minlength: 'minLength',
multiple: 'multiple',
muted: 'muted',
name: 'name',
nomodule: 'noModule',
nonce: 'nonce',
novalidate: 'noValidate',
open: 'open',
optimum: 'optimum',
pattern: 'pattern',
placeholder: 'placeholder',
playsinline: 'playsInline',
poster: 'poster',
preload: 'preload',
profile: 'profile',
radiogroup: 'radioGroup',
readonly: 'readOnly',
referrerpolicy: 'referrerPolicy',
rel: 'rel',
required: 'required',
reversed: 'reversed',
role: 'role',
rows: 'rows',
rowspan: 'rowSpan',
sandbox: 'sandbox',
scope: 'scope',
scoped: 'scoped',
scrolling: 'scrolling',
seamless: 'seamless',
selected: 'selected',
shape: 'shape',
size: 'size',
sizes: 'sizes',
span: 'span',
spellcheck: 'spellCheck',
src: 'src',
srcdoc: 'srcDoc',
srclang: 'srcLang',
srcset: 'srcSet',
start: 'start',
step: 'step',
style: 'style',
summary: 'summary',
tabindex: 'tabIndex',
target: 'target',
title: 'title',
type: 'type',
usemap: 'useMap',
value: 'value',
width: 'width',
wmode: 'wmode',
wrap: 'wrap',
// SVG
about: 'about',
accentheight: 'accentHeight',
'accent-height': 'accentHeight',
accumulate: 'accumulate',
additive: 'additive',
alignmentbaseline: 'alignmentBaseline',
'alignment-baseline': 'alignmentBaseline',
allowreorder: 'allowReorder',
alphabetic: 'alphabetic',
amplitude: 'amplitude',
arabicform: 'arabicForm',
'arabic-form': 'arabicForm',
ascent: 'ascent',
attributename: 'attributeName',
attributetype: 'attributeType',
autoreverse: 'autoReverse',
azimuth: 'azimuth',
basefrequency: 'baseFrequency',
baselineshift: 'baselineShift',
'baseline-shift': 'baselineShift',
baseprofile: 'baseProfile',
bbox: 'bbox',
begin: 'begin',
bias: 'bias',
by: 'by',
calcmode: 'calcMode',
capheight: 'capHeight',
'cap-height': 'capHeight',
clip: 'clip',
clippath: 'clipPath',
'clip-path': 'clipPath',
clippathunits: 'clipPathUnits',
cliprule: 'clipRule',
'clip-rule': 'clipRule',
color: 'color',
colorinterpolation: 'colorInterpolation',
'color-interpolation': 'colorInterpolation',
colorinterpolationfilters: 'colorInterpolationFilters',
'color-interpolation-filters': 'colorInterpolationFilters',
colorprofile: 'colorProfile',
'color-profile': 'colorProfile',
colorrendering: 'colorRendering',
'color-rendering': 'colorRendering',
contentscripttype: 'contentScriptType',
contentstyletype: 'contentStyleType',
cursor: 'cursor',
cx: 'cx',
cy: 'cy',
d: 'd',
datatype: 'datatype',
decelerate: 'decelerate',
descent: 'descent',
diffuseconstant: 'diffuseConstant',
direction: 'direction',
display: 'display',
divisor: 'divisor',
dominantbaseline: 'dominantBaseline',
'dominant-baseline': 'dominantBaseline',
dur: 'dur',
dx: 'dx',
dy: 'dy',
edgemode: 'edgeMode',
elevation: 'elevation',
enablebackground: 'enableBackground',
'enable-background': 'enableBackground',
end: 'end',
exponent: 'exponent',
externalresourcesrequired: 'externalResourcesRequired',
fill: 'fill',
fillopacity: 'fillOpacity',
'fill-opacity': 'fillOpacity',
fillrule: 'fillRule',
'fill-rule': 'fillRule',
filter: 'filter',
filterres: 'filterRes',
filterunits: 'filterUnits',
floodopacity: 'floodOpacity',
'flood-opacity': 'floodOpacity',
floodcolor: 'floodColor',
'flood-color': 'floodColor',
focusable: 'focusable',
fontfamily: 'fontFamily',
'font-family': 'fontFamily',
fontsize: 'fontSize',
'font-size': 'fontSize',
fontsizeadjust: 'fontSizeAdjust',
'font-size-adjust': 'fontSizeAdjust',
fontstretch: 'fontStretch',
'font-stretch': 'fontStretch',
fontstyle: 'fontStyle',
'font-style': 'fontStyle',
fontvariant: 'fontVariant',
'font-variant': 'fontVariant',
fontweight: 'fontWeight',
'font-weight': 'fontWeight',
format: 'format',
from: 'from',
fx: 'fx',
fy: 'fy',
g1: 'g1',
g2: 'g2',
glyphname: 'glyphName',
'glyph-name': 'glyphName',
glyphorientationhorizontal: 'glyphOrientationHorizontal',
'glyph-orientation-horizontal': 'glyphOrientationHorizontal',
glyphorientationvertical: 'glyphOrientationVertical',
'glyph-orientation-vertical': 'glyphOrientationVertical',
glyphref: 'glyphRef',
gradienttransform: 'gradientTransform',
gradientunits: 'gradientUnits',
hanging: 'hanging',
horizadvx: 'horizAdvX',
'horiz-adv-x': 'horizAdvX',
horizoriginx: 'horizOriginX',
'horiz-origin-x': 'horizOriginX',
ideographic: 'ideographic',
imagerendering: 'imageRendering',
'image-rendering': 'imageRendering',
in2: 'in2',
in: 'in',
inlist: 'inlist',
intercept: 'intercept',
k1: 'k1',
k2: 'k2',
k3: 'k3',
k4: 'k4',
k: 'k',
kernelmatrix: 'kernelMatrix',
kernelunitlength: 'kernelUnitLength',
kerning: 'kerning',
keypoints: 'keyPoints',
keysplines: 'keySplines',
keytimes: 'keyTimes',
lengthadjust: 'lengthAdjust',
letterspacing: 'letterSpacing',
'letter-spacing': 'letterSpacing',
lightingcolor: 'lightingColor',
'lighting-color': 'lightingColor',
limitingconeangle: 'limitingConeAngle',
local: 'local',
markerend: 'markerEnd',
'marker-end': 'markerEnd',
markerheight: 'markerHeight',
markermid: 'markerMid',
'marker-mid': 'markerMid',
markerstart: 'markerStart',
'marker-start': 'markerStart',
markerunits: 'markerUnits',
markerwidth: 'markerWidth',
mask: 'mask',
maskcontentunits: 'maskContentUnits',
maskunits: 'maskUnits',
mathematical: 'mathematical',
mode: 'mode',
numoctaves: 'numOctaves',
offset: 'offset',
opacity: 'opacity',
operator: 'operator',
order: 'order',
orient: 'orient',
orientation: 'orientation',
origin: 'origin',
overflow: 'overflow',
overlineposition: 'overlinePosition',
'overline-position': 'overlinePosition',
overlinethickness: 'overlineThickness',
'overline-thickness': 'overlineThickness',
paintorder: 'paintOrder',
'paint-order': 'paintOrder',
panose1: 'panose1',
'panose-1': 'panose1',
pathlength: 'pathLength',
patterncontentunits: 'patternContentUnits',
patterntransform: 'patternTransform',
patternunits: 'patternUnits',
pointerevents: 'pointerEvents',
'pointer-events': 'pointerEvents',
points: 'points',
pointsatx: 'pointsAtX',
pointsaty: 'pointsAtY',
pointsatz: 'pointsAtZ',
prefix: 'prefix',
preservealpha: 'preserveAlpha',
preserveaspectratio: 'preserveAspectRatio',
primitiveunits: 'primitiveUnits',
property: 'property',
r: 'r',
radius: 'radius',
refx: 'refX',
refy: 'refY',
renderingintent: 'renderingIntent',
'rendering-intent': 'renderingIntent',
repeatcount: 'repeatCount',
repeatdur: 'repeatDur',
requiredextensions: 'requiredExtensions',
requiredfeatures: 'requiredFeatures',
resource: 'resource',
restart: 'restart',
result: 'result',
results: 'results',
rotate: 'rotate',
rx: 'rx',
ry: 'ry',
scale: 'scale',
security: 'security',
seed: 'seed',
shaperendering: 'shapeRendering',
'shape-rendering': 'shapeRendering',
slope: 'slope',
spacing: 'spacing',
specularconstant: 'specularConstant',
specularexponent: 'specularExponent',
speed: 'speed',
spreadmethod: 'spreadMethod',
startoffset: 'startOffset',
stddeviation: 'stdDeviation',
stemh: 'stemh',
stemv: 'stemv',
stitchtiles: 'stitchTiles',
stopcolor: 'stopColor',
'stop-color': 'stopColor',
stopopacity: 'stopOpacity',
'stop-opacity': 'stopOpacity',
strikethroughposition: 'strikethroughPosition',
'strikethrough-position': 'strikethroughPosition',
strikethroughthickness: 'strikethroughThickness',
'strikethrough-thickness': 'strikethroughThickness',
string: 'string',
stroke: 'stroke',
strokedasharray: 'strokeDasharray',
'stroke-dasharray': 'strokeDasharray',
strokedashoffset: 'strokeDashoffset',
'stroke-dashoffset': 'strokeDashoffset',
strokelinecap: 'strokeLinecap',
'stroke-linecap': 'strokeLinecap',
strokelinejoin: 'strokeLinejoin',
'stroke-linejoin': 'strokeLinejoin',
strokemiterlimit: 'strokeMiterlimit',
'stroke-miterlimit': 'strokeMiterlimit',
strokewidth: 'strokeWidth',
'stroke-width': 'strokeWidth',
strokeopacity: 'strokeOpacity',
'stroke-opacity': 'strokeOpacity',
suppresscontenteditablewarning: 'suppressContentEditableWarning',
suppresshydrationwarning: 'suppressHydrationWarning',
surfacescale: 'surfaceScale',
systemlanguage: 'systemLanguage',
tablevalues: 'tableValues',
targetx: 'targetX',
targety: 'targetY',
textanchor: 'textAnchor',
'text-anchor': 'textAnchor',
textdecoration: 'textDecoration',
'text-decoration': 'textDecoration',
textlength: 'textLength',
textrendering: 'textRendering',
'text-rendering': 'textRendering',
to: 'to',
transform: 'transform',
typeof: 'typeof',
u1: 'u1',
u2: 'u2',
underlineposition: 'underlinePosition',
'underline-position': 'underlinePosition',
underlinethickness: 'underlineThickness',
'underline-thickness': 'underlineThickness',
unicode: 'unicode',
unicodebidi: 'unicodeBidi',
'unicode-bidi': 'unicodeBidi',
unicoderange: 'unicodeRange',
'unicode-range': 'unicodeRange',
unitsperem: 'unitsPerEm',
'units-per-em': 'unitsPerEm',
unselectable: 'unselectable',
valphabetic: 'vAlphabetic',
'v-alphabetic': 'vAlphabetic',
values: 'values',
vectoreffect: 'vectorEffect',
'vector-effect': 'vectorEffect',
version: 'version',
vertadvy: 'vertAdvY',
'vert-adv-y': 'vertAdvY',
vertoriginx: 'vertOriginX',
'vert-origin-x': 'vertOriginX',
vertoriginy: 'vertOriginY',
'vert-origin-y': 'vertOriginY',
vhanging: 'vHanging',
'v-hanging': 'vHanging',
videographic: 'vIdeographic',
'v-ideographic': 'vIdeographic',
viewbox: 'viewBox',
viewtarget: 'viewTarget',
visibility: 'visibility',
vmathematical: 'vMathematical',
'v-mathematical': 'vMathematical',
vocab: 'vocab',
widths: 'widths',
wordspacing: 'wordSpacing',
'word-spacing': 'wordSpacing',
writingmode: 'writingMode',
'writing-mode': 'writingMode',
x1: 'x1',
x2: 'x2',
x: 'x',
xchannelselector: 'xChannelSelector',
xheight: 'xHeight',
'x-height': 'xHeight',
xlinkactuate: 'xlinkActuate',
'xlink:actuate': 'xlinkActuate',
xlinkarcrole: 'xlinkArcrole',
'xlink:arcrole': 'xlinkArcrole',
xlinkhref: 'xlinkHref',
'xlink:href': 'xlinkHref',
xlinkrole: 'xlinkRole',
'xlink:role': 'xlinkRole',
xlinkshow: 'xlinkShow',
'xlink:show': 'xlinkShow',
xlinktitle: 'xlinkTitle',
'xlink:title': 'xlinkTitle',
xlinktype: 'xlinkType',
'xlink:type': 'xlinkType',
xmlbase: 'xmlBase',
'xml:base': 'xmlBase',
xmllang: 'xmlLang',
'xml:lang': 'xmlLang',
xmlns: 'xmlns',
'xml:space': 'xmlSpace',
xmlnsxlink: 'xmlnsXlink',
'xmlns:xlink': 'xmlnsXlink',
xmlspace: 'xmlSpace',
y1: 'y1',
y2: 'y2',
y: 'y',
ychannelselector: 'yChannelSelector',
z: 'z',
zoomandpan: 'zoomAndPan'
};
var validateProperty$1 = function () {};
{
var warnedProperties$1 = {};
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 + ']*$');
validateProperty$1 = function (tagName, name, value, eventRegistry) {
if (hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) {
return true;
}
var lowerCasedName = name.toLowerCase();
if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') {
error('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;
} // We can't rely on the event system being injected on the server.
if (eventRegistry != null) {
var registrationNameDependencies = eventRegistry.registrationNameDependencies,
possibleRegistrationNames = eventRegistry.possibleRegistrationNames;
if (registrationNameDependencies.hasOwnProperty(name)) {
return true;
}
var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null;
if (registrationName != null) {
error('Invalid event handler property `%s`. Did you mean `%s`?', name, registrationName);
warnedProperties$1[name] = true;
return true;
}
if (EVENT_NAME_REGEX.test(name)) {
error('Unknown event handler property `%s`. It will be ignored.', name);
warnedProperties$1[name] = true;
return true;
}
} else if (EVENT_NAME_REGEX.test(name)) {
// If no event plugins have been injected, we are in a server environment.
// 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)) {
error('Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.', name);
}
warnedProperties$1[name] = true;
return true;
} // Let the ARIA attribute hook validate ARIA attributes
if (rARIA$1.test(name) || rARIACamel$1.test(name)) {
return true;
}
if (lowerCasedName === 'innerhtml') {
error('Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.');
warnedProperties$1[name] = true;
return true;
}
if (lowerCasedName === 'aria') {
error('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') {
error('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)) {
error('Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.', name);
warnedProperties$1[name] = true;
return true;
}
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) {
error('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.
error('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' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
if (value) {
error('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 {
error('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;
} // Now that we've validated casing, do not validate
// data types for reserved props
if (isReserved) {
return true;
} // Warn when a known attribute is a bad type
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) {
error('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;
};
}
var warnUnknownProperties = function (type, props, eventRegistry) {
{
var unknownProps = [];
for (var key in props) {
var isValid = validateProperty$1(type, key, props[key], eventRegistry);
if (!isValid) {
unknownProps.push(key);
}
}
var unknownPropString = unknownProps.map(function (prop) {
return '`' + prop + '`';
}).join(', ');
if (unknownProps.length === 1) {
error('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://reactjs.org/link/attribute-behavior ', unknownPropString, type);
} else if (unknownProps.length > 1) {
error('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://reactjs.org/link/attribute-behavior ', unknownPropString, type);
}
}
};
function validateProperties$2(type, props, eventRegistry) {
if (isCustomComponent(type, props)) {
return;
}
warnUnknownProperties(type, props, eventRegistry);
}
var warnValidStyle = function () {};
{
// 'msTransform' is correct, but the other prefixes should be capitalized
var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
var msPattern = /^-ms-/;
var hyphenPattern = /-(.)/g; // style values shouldn't contain a semicolon
var badStyleValueWithSemicolonPattern = /;\s*$/;
var warnedStyleNames = {};
var warnedStyleValues = {};
var warnedForNaNValue = false;
var warnedForInfinityValue = false;
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;
error('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, 'ms-')));
};
var warnBadVendoredStyleName = function (name) {
if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
return;
}
warnedStyleNames[name] = true;
error('Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1));
};
var warnStyleValueWithSemicolon = function (name, value) {
if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
return;
}