mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Moved unknown-prop warning into a devtool
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
|
||||
var ReactDOMComponentTree = require('ReactDOMComponentTree');
|
||||
var ReactDOMDevtools = require('ReactDOMDevtools');
|
||||
var ReactDOMUnknownPropertyDevtool = require('ReactDOMUnknownPropertyDevtool');
|
||||
var ReactDefaultInjection = require('ReactDefaultInjection');
|
||||
var ReactMount = require('ReactMount');
|
||||
var ReactPerf = require('ReactPerf');
|
||||
@@ -136,6 +137,8 @@ if (__DEV__) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOMDevtools.addDevtool(new ReactDOMUnknownPropertyDevtool());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
'use strict';
|
||||
|
||||
var DOMProperty = require('DOMProperty');
|
||||
var EventPluginRegistry = require('EventPluginRegistry');
|
||||
var ReactDOMDevtools = require('ReactDOMDevtools');
|
||||
var ReactPerf = require('ReactPerf');
|
||||
|
||||
var quoteAttributeValueForBrowser = require('quoteAttributeValueForBrowser');
|
||||
@@ -51,59 +51,6 @@ function shouldIgnoreValue(propertyInfo, value) {
|
||||
(propertyInfo.hasOverloadedBooleanValue && value === false);
|
||||
}
|
||||
|
||||
if (__DEV__) {
|
||||
var reactProps = {
|
||||
children: true,
|
||||
dangerouslySetInnerHTML: true,
|
||||
key: true,
|
||||
ref: true,
|
||||
};
|
||||
var warnedProperties = {};
|
||||
|
||||
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
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Operations for dealing with DOM properties.
|
||||
*/
|
||||
@@ -140,6 +87,7 @@ var DOMPropertyOperations = {
|
||||
* @return {?string} Markup string, or null if the property was invalid.
|
||||
*/
|
||||
createMarkupForProperty: function(name, value) {
|
||||
ReactDOMDevtools.emitEvent('createMarkupForProperty', {name, value});
|
||||
var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ?
|
||||
DOMProperty.properties[name] : null;
|
||||
if (propertyInfo) {
|
||||
@@ -157,8 +105,6 @@ var DOMPropertyOperations = {
|
||||
return '';
|
||||
}
|
||||
return name + '=' + quoteAttributeValueForBrowser(value);
|
||||
} else if (__DEV__) {
|
||||
warnUnknownProperty(name);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
@@ -185,6 +131,7 @@ var DOMPropertyOperations = {
|
||||
* @param {*} value
|
||||
*/
|
||||
setValueForProperty: function(node, name, value) {
|
||||
ReactDOMDevtools.emitEvent('setValueForProperty', {node, name, value});
|
||||
var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ?
|
||||
DOMProperty.properties[name] : null;
|
||||
if (propertyInfo) {
|
||||
@@ -219,8 +166,6 @@ var DOMPropertyOperations = {
|
||||
}
|
||||
} else if (DOMProperty.isCustomAttribute(name)) {
|
||||
DOMPropertyOperations.setValueForAttribute(node, name, value);
|
||||
} else if (__DEV__) {
|
||||
warnUnknownProperty(name);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -242,6 +187,7 @@ var DOMPropertyOperations = {
|
||||
* @param {string} name
|
||||
*/
|
||||
deleteValueForProperty: function(node, name) {
|
||||
ReactDOMDevtools.emitEvent('deleteValueForProperty', {node, name});
|
||||
var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ?
|
||||
DOMProperty.properties[name] : null;
|
||||
if (propertyInfo) {
|
||||
@@ -263,8 +209,6 @@ var DOMPropertyOperations = {
|
||||
}
|
||||
} else if (DOMProperty.isCustomAttribute(name)) {
|
||||
node.removeAttribute(name);
|
||||
} else if (__DEV__) {
|
||||
warnUnknownProperty(name);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -50,41 +50,6 @@ describe('DOMPropertyOperations', function() {
|
||||
)).toBe('id="simple"');
|
||||
});
|
||||
|
||||
it('should warn about incorrect casing on properties', function() {
|
||||
spyOn(console, 'error');
|
||||
expect(DOMPropertyOperations.createMarkupForProperty(
|
||||
'tabindex',
|
||||
'1'
|
||||
)).toBe(null);
|
||||
expect(console.error.argsForCall.length).toBe(1);
|
||||
expect(console.error.argsForCall[0][0]).toContain('tabIndex');
|
||||
});
|
||||
|
||||
it('should warn about incorrect casing on event handlers', function() {
|
||||
spyOn(console, 'error');
|
||||
expect(DOMPropertyOperations.createMarkupForProperty(
|
||||
'onclick',
|
||||
'1'
|
||||
)).toBe(null);
|
||||
expect(DOMPropertyOperations.createMarkupForProperty(
|
||||
'onKeydown',
|
||||
'1'
|
||||
)).toBe(null);
|
||||
expect(console.error.argsForCall.length).toBe(2);
|
||||
expect(console.error.argsForCall[0][0]).toContain('onClick');
|
||||
expect(console.error.argsForCall[1][0]).toContain('onKeyDown');
|
||||
});
|
||||
|
||||
it('should warn about class', function() {
|
||||
spyOn(console, 'error');
|
||||
expect(DOMPropertyOperations.createMarkupForProperty(
|
||||
'class',
|
||||
'muffins'
|
||||
)).toBe(null);
|
||||
expect(console.error.argsForCall.length).toBe(1);
|
||||
expect(console.error.argsForCall[0][0]).toContain('className');
|
||||
});
|
||||
|
||||
it('should create markup for boolean properties', function() {
|
||||
expect(DOMPropertyOperations.createMarkupForProperty(
|
||||
'checked',
|
||||
|
||||
@@ -1087,5 +1087,28 @@ describe('ReactDOMComponent', function() {
|
||||
'See Link > a > ... > Link > a.'
|
||||
);
|
||||
});
|
||||
|
||||
it('should warn about incorrect casing on properties', function() {
|
||||
spyOn(console, 'error');
|
||||
ReactDOMServer.renderToString(React.createElement('input', {type: 'text', tabindex: '1'}));
|
||||
expect(console.error.argsForCall.length).toBe(1);
|
||||
expect(console.error.argsForCall[0][0]).toContain('tabIndex');
|
||||
});
|
||||
|
||||
it('should warn about incorrect casing on event handlers', function() {
|
||||
spyOn(console, 'error');
|
||||
ReactDOMServer.renderToString(React.createElement('input', {type: 'text', onclick: '1'}));
|
||||
ReactDOMServer.renderToString(React.createElement('input', {type: 'text', onKeydown: '1'}));
|
||||
expect(console.error.argsForCall.length).toBe(2);
|
||||
expect(console.error.argsForCall[0][0]).toContain('onClick');
|
||||
expect(console.error.argsForCall[1][0]).toContain('onKeyDown');
|
||||
});
|
||||
|
||||
it('should warn about class', function() {
|
||||
spyOn(console, 'error');
|
||||
ReactDOMServer.renderToString(React.createElement('div', {class: 'muffins'}));
|
||||
expect(console.error.argsForCall.length).toBe(1);
|
||||
expect(console.error.argsForCall[0][0]).toContain('className');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* Copyright 2013-2015, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @providesModule ReactDOMUnknownPropertyDevtool
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var DOMProperty = require('DOMProperty');
|
||||
var EventPluginRegistry = require('EventPluginRegistry');
|
||||
|
||||
var warning = require('warning');
|
||||
|
||||
if (__DEV__) {
|
||||
var reactProps = {
|
||||
children: true,
|
||||
dangerouslySetInnerHTML: true,
|
||||
key: true,
|
||||
ref: true,
|
||||
};
|
||||
var warnedProperties = {};
|
||||
|
||||
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
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
class ReactDOMUnknownPropertyDevtool {
|
||||
handleEvent(eventName, eventData) {
|
||||
switch (eventName) {
|
||||
case 'createMarkupForProperty':
|
||||
case 'setValueForProperty':
|
||||
case 'deleteValueForProperty':
|
||||
var name = eventData.name;
|
||||
if (!DOMProperty.properties.hasOwnProperty(name) &&
|
||||
!DOMProperty.isCustomAttribute(name)) {
|
||||
warnUnknownProperty(name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ReactDOMUnknownPropertyDevtool;
|
||||
Reference in New Issue
Block a user