var validateProperty = function(tagName, name, debugID) { if ( DOMProperty.properties.hasOwnProperty(name) || DOMProperty.isCustomAttribute(name) ) { return true; } if ( (reactProps.hasOwnProperty(name) && reactProps[name]) || (warnedProperties.hasOwnProperty(name) && warnedProperties[name]) ) { return true; } if (EventPluginRegistry.registrationNameModules.hasOwnProperty(name)) { return true; } warnedProperties[name] = true; var lowerCasedName = name.toLowerCase(); // data-* attributes should be lowercase; suggest the lowercase version var standardName = DOMProperty.isCustomAttribute(lowerCasedName) ? lowerCasedName : DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? DOMProperty.getPossibleStandardName[lowerCasedName] : null; var registrationName = EventPluginRegistry.possibleRegistrationNames.hasOwnProperty( lowerCasedName, ) ? EventPluginRegistry.possibleRegistrationNames[lowerCasedName] : null; if (standardName != null) { warning( false, 'Unknown DOM property %s. Did you mean %s?%s', name, standardName, getStackAddendum(debugID), ); return true; } else if (registrationName != null) { warning( false, 'Unknown event handler property %s. Did you mean `%s`?%s', name, registrationName, getStackAddendum(debugID), ); return true; } else { // We were unable to guess which prop the user intended. // It is likely that the user was just blindly spreading/forwarding props // Components should be careful to only render valid props/attributes. // Warning will be invoked in warnUnknownProperties to allow grouping. return false; } };
var warnUnknownProperty = function(name) { if (reactProps.hasOwnProperty(name) && reactProps[name] || warnedProperties.hasOwnProperty(name) && warnedProperties[name]) { return; } warnedProperties[name] = true; var lowerCasedName = name.toLowerCase(); // data-* attributes should be lowercase; suggest the lowercase version var standardName = ( DOMProperty.isCustomAttribute(lowerCasedName) ? lowerCasedName : DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? DOMProperty.getPossibleStandardName[lowerCasedName] : null ); // For now, only warn when we have a suggested correction. This prevents // logging too much when using transferPropsTo. warning( standardName == null, 'Unknown DOM property %s. Did you mean %s?', name, standardName ); var registrationName = ( EventPluginRegistry.possibleRegistrationNames.hasOwnProperty( lowerCasedName ) ? EventPluginRegistry.possibleRegistrationNames[lowerCasedName] : null ); warning( registrationName == null, 'Unknown event handler property %s. Did you mean `%s`?', name, registrationName ); };
var warnUnknownProperty = function(tagName, name, debugID) { if (DOMProperty.properties.hasOwnProperty(name) || DOMProperty.isCustomAttribute(name)) { return; } if (reactProps.hasOwnProperty(name) && reactProps[name] || warnedProperties.hasOwnProperty(name) && warnedProperties[name]) { return; } if (EventPluginRegistry.registrationNameModules.hasOwnProperty(name)) { return; } warnedProperties[name] = true; var lowerCasedName = name.toLowerCase(); // data-* attributes should be lowercase; suggest the lowercase version var standardName = ( DOMProperty.isCustomAttribute(lowerCasedName) ? lowerCasedName : DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? DOMProperty.getPossibleStandardName[lowerCasedName] : null ); var registrationName = ( EventPluginRegistry.possibleRegistrationNames.hasOwnProperty( lowerCasedName ) ? EventPluginRegistry.possibleRegistrationNames[lowerCasedName] : null ); if (standardName != null) { warning( standardName == null, 'Unknown DOM property %s. Did you mean %s?%s', name, standardName, ReactComponentTreeDevtool.getStackAddendumByID(debugID) ); } else if (registrationName != null) { warning( registrationName == null, 'Unknown event handler property %s. Did you mean `%s`?%s', name, registrationName, ReactComponentTreeDevtool.getStackAddendumByID(debugID) ); } else { // We were unable to guess which prop the user intended. // It is likely that the user was just blindly spreading/forwarding props // Components should be careful to only render valid props/attributes. warning( false, 'Unknown prop `%s` on <%s> tag. Remove this prop from the element. ' + 'For details, see https://fb.me/react-unknown-prop%s', name, tagName, ReactComponentTreeDevtool.getStackAddendumByID(debugID) ); } };
var validateProperty = function(tagName, name, value) { if (hasOwnProperty.call(warnedProperties, name) && warnedProperties[name]) { return true; } if (EventPluginRegistry.registrationNameModules.hasOwnProperty(name)) { return true; } if ( EventPluginRegistry.plugins.length === 0 && EVENT_NAME_REGEX.test(name) ) { // If no event plugins have been injected, we might be in a server environment. // Don't check events in this case. return true; } var lowerCasedName = name.toLowerCase(); var registrationName = EventPluginRegistry.possibleRegistrationNames.hasOwnProperty( lowerCasedName, ) ? EventPluginRegistry.possibleRegistrationNames[lowerCasedName] : null; if (registrationName != null) { warning( false, 'Invalid event handler property `%s`. Did you mean `%s`?%s', name, registrationName, getStackAddendum(), ); warnedProperties[name] = true; return true; } if (lowerCasedName.indexOf('on') === 0) { warning( false, 'Unknown event handler property `%s`. It will be ignored.%s', name, getStackAddendum(), ); warnedProperties[name] = true; return true; } // Let the ARIA attribute hook validate ARIA attributes if (rARIA.test(name) || rARIACamel.test(name)) { return true; } 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.', ); warnedProperties[name] = true; return true; } if (lowerCasedName === 'innerhtml') { warning( false, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.', ); warnedProperties[name] = true; return true; } if (lowerCasedName === 'aria') { warning( false, 'The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.', ); warnedProperties[name] = true; return true; } if ( lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string' ) { warning( false, 'Received a `%s` for string attribute `is`. If this is expected, cast ' + 'the value to a string.%s', typeof value, getStackAddendum(), ); warnedProperties[name] = true; return true; } if (typeof value === 'number' && isNaN(value)) { warning( false, 'Received NaN for numeric attribute `%s`. If this is expected, cast ' + 'the value to a string.%s', name, getStackAddendum(), ); warnedProperties[name] = true; return true; } const isReserved = DOMProperty.isReservedProp(name); // 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(), ); warnedProperties[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(), ); warnedProperties[name] = true; return true; } if (typeof value === 'boolean') { warning( DOMProperty.shouldAttributeAcceptBooleanValue(name), 'Received `%s` for non-boolean attribute `%s`. If this is expected, cast ' + 'the value to a string.%s', value, name, getStackAddendum(), ); warnedProperties[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 (!DOMProperty.shouldSetAttribute(name, value)) { warnedProperties[name] = true; return false; } return true; };