@samitouri / QOS-React-2 / commits / 9ad4be0316

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 };