@samitouri / QOS-React-2 / commits / 5ceb22953c

Add support for "invalid" event within Form elements

Fixes #5152

Tom Duncalf committed Oct 15, 2015 at 19:11 UTC 5ceb22953cc9d66f68fed44c26e93506d2f5e9eb
3 files changed +37 -4
src/renderers/dom/client/eventPlugins/SimpleEventPlugin.js
+8
@@ -177,6 +177,12 @@ var eventTypes = {
177 captured: keyOf({onInputCapture: true}),
178 },
179 },
180 + invalid: {
181 + phasedRegistrationNames: {
182 + bubbled: keyOf({onInvalid: true}),
183 + captured: keyOf({onInvalidCapture: true}),
184 + },
185 + },
186 keyDown: {
187 phasedRegistrationNames: {
188 bubbled: keyOf({onKeyDown: true}),
@@ -404,6 +410,7 @@ var topLevelEventsToDispatchConfig = {
410 topError: eventTypes.error,
411 topFocus: eventTypes.focus,
412 topInput: eventTypes.input,
413 + topInvalid: eventTypes.invalid,
414 topKeyDown: eventTypes.keyDown,
415 topKeyPress: eventTypes.keyPress,
416 topKeyUp: eventTypes.keyUp,
@@ -480,6 +487,7 @@ var SimpleEventPlugin = {
487 case topLevelTypes.topEnded:
488 case topLevelTypes.topError:
489 case topLevelTypes.topInput:
490 + case topLevelTypes.topInvalid:
491 case topLevelTypes.topLoad:
492 case topLevelTypes.topLoadedData:
493 case topLevelTypes.topLoadedMetadata:
src/renderers/dom/shared/ReactDOMComponent.js
+28 -4
@@ -414,6 +414,17 @@ function trapBubbledEventsLocal() {
414 ),
415 ];
416 break;
417 + case 'input':
418 + case 'select':
419 + case 'textarea':
420 + inst._wrapperState.listeners = [
421 + ReactBrowserEventEmitter.trapBubbledEvent(
422 + EventConstants.topLevelTypes.topInvalid,
423 + 'invalid',
424 + node
425 + ),
426 + ];
427 + break;
428 }
429 }
430
@@ -557,15 +568,13 @@ ReactDOMComponent.Mixin = {
568 case 'form':
569 case 'video':
570 case 'audio':
560 - this._wrapperState = {
561 - listeners: null,
562 - };
563 - transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this);
571 + this._setupTrapBubbledEventsLocal(transaction);
572 break;
573 case 'button':
574 props = ReactDOMButton.getNativeProps(this, props, nativeParent);
575 break;
576 case 'input':
577 + this._setupTrapBubbledEventsLocal(transaction);
578 ReactDOMInput.mountWrapper(this, props, nativeParent);
579 props = ReactDOMInput.getNativeProps(this, props);
580 break;
@@ -574,10 +583,12 @@ ReactDOMComponent.Mixin = {
583 props = ReactDOMOption.getNativeProps(this, props);
584 break;
585 case 'select':
586 + this._setupTrapBubbledEventsLocal(transaction);
587 ReactDOMSelect.mountWrapper(this, props, nativeParent);
588 props = ReactDOMSelect.getNativeProps(this, props);
589 break;
590 case 'textarea':
591 + this._setupTrapBubbledEventsLocal(transaction);
592 ReactDOMTextarea.mountWrapper(this, props, nativeParent);
593 props = ReactDOMTextarea.getNativeProps(this, props);
594 break;
@@ -686,6 +697,19 @@ ReactDOMComponent.Mixin = {
697 return mountImage;
698 },
699
700 + /**
701 + * Setup this component to trap non-bubbling events locally
702 + *
703 + * @private
704 + * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
705 + */
706 + _setupTrapBubbledEventsLocal: function(transaction) {
707 + this._wrapperState = {
708 + listeners: null,
709 + };
710 + transaction.getReactMountReady().enqueue(trapBubbledEventsLocal, this);
711 + },
712 +
713 /**
714 * Creates markup for the open tag and all attributes.
715 *
src/renderers/shared/event/EventConstants.js
+1
@@ -47,6 +47,7 @@ var topLevelTypes = keyMirror({
47 topError: null,
48 topFocus: null,
49 topInput: null,
50 + topInvalid: null,
51 topKeyDown: null,
52 topKeyPress: null,
53 topKeyUp: null,