Warn on missing event handler properties
Fixes #3548. Warns on properties that are case-insensitive matches for registered event names (e.g. "onclick" instead of "onClick").
Ali Ukani committed
Nov 2, 2015 at 04:27 UTC
9ad4be0316d36e446eabd280f680a1b8632323c5
3 files changed
+55
-1
src/renderers/dom/shared/DOMPropertyOperations.js
+15
@@ -13,6 +13,7 @@
13
'use strict';
14
15
var DOMProperty = require('DOMProperty');
16
+var EventPluginRegistry = require('EventPluginRegistry');
17
var ReactPerf = require('ReactPerf');
18
19
var quoteAttributeValueForBrowser = require('quoteAttributeValueForBrowser');
@@ -87,6 +88,20 @@ if (__DEV__) {
88
standardName
89
);
90
91
+ var registrationName = (
92
+ EventPluginRegistry.possibleRegistrationNames.hasOwnProperty(
93
+ lowerCasedName
94
+ ) ?
95
+ EventPluginRegistry.possibleRegistrationNames[lowerCasedName] :
96
+ null
97
+ );
98
+
99
+ warning(
100
+ registrationName == null,
101
+ 'Unknown event handler property %s. Did you mean `%s`?',
102
+ name,
103
+ registrationName
104
+ );
105
};
106
}
107
src/renderers/dom/shared/__tests__/DOMPropertyOperations-test.js
+16
-1
@@ -50,7 +50,7 @@ describe('DOMPropertyOperations', function() {
50
)).toBe('id="simple"');
51
});
52
53
- it('should warn about incorrect casing', function() {
53
+ it('should warn about incorrect casing on properties', function() {
54
spyOn(console, 'error');
55
expect(DOMPropertyOperations.createMarkupForProperty(
56
'tabindex',
@@ -60,6 +60,21 @@ describe('DOMPropertyOperations', function() {
60
expect(console.error.argsForCall[0][0]).toContain('tabIndex');
61
});
62
63
+ it('should warn about incorrect casing on event handlers', function() {
64
+ spyOn(console, 'error');
65
+ expect(DOMPropertyOperations.createMarkupForProperty(
66
+ 'onclick',
67
+ '1'
68
+ )).toBe(null);
69
+ expect(DOMPropertyOperations.createMarkupForProperty(
70
+ 'onKeydown',
71
+ '1'
72
+ )).toBe(null);
73
+ expect(console.error.argsForCall.length).toBe(2);
74
+ expect(console.error.argsForCall[0][0]).toContain('onClick');
75
+ expect(console.error.argsForCall[1][0]).toContain('onKeyDown');
76
+ });
77
+
78
it('should warn about class', function() {
79
spyOn(console, 'error');
80
expect(DOMPropertyOperations.createMarkupForProperty(
src/renderers/shared/event/EventPluginRegistry.js
+24
@@ -128,6 +128,12 @@ function publishRegistrationName(registrationName, PluginModule, eventName) {
128
EventPluginRegistry.registrationNameModules[registrationName] = PluginModule;
129
EventPluginRegistry.registrationNameDependencies[registrationName] =
130
PluginModule.eventTypes[eventName].dependencies;
131
+
132
+ if (__DEV__) {
133
+ var lowerCasedName = registrationName.toLowerCase();
134
+ EventPluginRegistry.possibleRegistrationNames[lowerCasedName] =
135
+ registrationName;
136
+ }
137
}
138
139
/**
@@ -157,6 +163,14 @@ var EventPluginRegistry = {
163
*/
164
registrationNameDependencies: {},
165
166
+ /**
167
+ * Mapping from lowercase registration names to the properly cased version,
168
+ * used to warn in the case of missing event handlers. Available
169
+ * only in __DEV__.
170
+ * @type {Object}
171
+ */
172
+ possibleRegistrationNames: __DEV__ ? {} : null,
173
+
174
/**
175
* Injects an ordering of plugins (by plugin name). This allows the ordering
176
* to be decoupled from injection of the actual plugins so that ordering is
@@ -265,6 +279,16 @@ var EventPluginRegistry = {
279
delete registrationNameModules[registrationName];
280
}
281
}
282
+
283
+ if (__DEV__) {
284
+ var possibleRegistrationNames =
285
+ EventPluginRegistry.possibleRegistrationNames;
286
+ for (var lowerCasedName in possibleRegistrationNames) {
287
+ if (possibleRegistrationNames.hasOwnProperty(lowerCasedName)) {
288
+ delete possibleRegistrationNames[lowerCasedName];
289
+ }
290
+ }
291
+ }
292
},
293
294
};