mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Stopgap fix for element disabling (#8387)
Fix for #8308. This is a bad hack -- EventPluginHub.getListener isn't even DOM-specific -- but this works for now and lets us release 15.4.1.
(cherry picked from commit c7129ce1f0)
This commit is contained in:
@@ -156,18 +156,6 @@ function isInteractive(tag) {
|
||||
);
|
||||
}
|
||||
|
||||
function shouldPreventMouseEvent(inst) {
|
||||
if (inst) {
|
||||
var disabled = inst._currentElement && inst._currentElement.props.disabled;
|
||||
|
||||
if (disabled) {
|
||||
return isInteractive(inst._tag);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
var SimpleEventPlugin: PluginModule<MouseEvent> = {
|
||||
|
||||
eventTypes: eventTypes,
|
||||
@@ -243,10 +231,7 @@ var SimpleEventPlugin: PluginModule<MouseEvent> = {
|
||||
case 'topMouseDown':
|
||||
case 'topMouseMove':
|
||||
case 'topMouseUp':
|
||||
// Disabled elements should not respond to mouse events
|
||||
if (shouldPreventMouseEvent(targetInst)) {
|
||||
return null;
|
||||
}
|
||||
// TODO: Disabled elements should not respond to mouse events
|
||||
/* falls through */
|
||||
case 'topMouseOut':
|
||||
case 'topMouseOver':
|
||||
|
||||
@@ -17,16 +17,14 @@ describe('SimpleEventPlugin', function() {
|
||||
var ReactDOM;
|
||||
var ReactTestUtils;
|
||||
|
||||
var onClick = jest.fn();
|
||||
var onClick;
|
||||
|
||||
function expectClickThru(element) {
|
||||
onClick.mockClear();
|
||||
ReactTestUtils.SimulateNative.click(ReactDOM.findDOMNode(element));
|
||||
expect(onClick.mock.calls.length).toBe(1);
|
||||
}
|
||||
|
||||
function expectNoClickThru(element) {
|
||||
onClick.mockClear();
|
||||
ReactTestUtils.SimulateNative.click(ReactDOM.findDOMNode(element));
|
||||
expect(onClick.mock.calls.length).toBe(0);
|
||||
}
|
||||
@@ -40,6 +38,8 @@ describe('SimpleEventPlugin', function() {
|
||||
React = require('React');
|
||||
ReactDOM = require('ReactDOM');
|
||||
ReactTestUtils = require('ReactTestUtils');
|
||||
|
||||
onClick = jest.fn();
|
||||
});
|
||||
|
||||
it('A non-interactive tags click when disabled', function() {
|
||||
@@ -53,7 +53,48 @@ describe('SimpleEventPlugin', function() {
|
||||
);
|
||||
var child = ReactDOM.findDOMNode(element).firstChild;
|
||||
|
||||
onClick.mockClear();
|
||||
ReactTestUtils.SimulateNative.click(child);
|
||||
expect(onClick.mock.calls.length).toBe(1);
|
||||
});
|
||||
|
||||
it('does not register a click when clicking a child of a disabled element', function() {
|
||||
var element = ReactTestUtils.renderIntoDocument(
|
||||
<button onClick={onClick} disabled={true}><span /></button>
|
||||
);
|
||||
var child = ReactDOM.findDOMNode(element).querySelector('span');
|
||||
|
||||
ReactTestUtils.SimulateNative.click(child);
|
||||
expect(onClick.mock.calls.length).toBe(0);
|
||||
});
|
||||
|
||||
it('triggers click events for children of disabled elements', function() {
|
||||
var element = ReactTestUtils.renderIntoDocument(
|
||||
<button disabled={true}><span onClick={onClick} /></button>
|
||||
);
|
||||
var child = ReactDOM.findDOMNode(element).querySelector('span');
|
||||
|
||||
ReactTestUtils.SimulateNative.click(child);
|
||||
expect(onClick.mock.calls.length).toBe(1);
|
||||
});
|
||||
|
||||
it('triggers parent captured click events when target is a child of a disabled elements', function() {
|
||||
var element = ReactTestUtils.renderIntoDocument(
|
||||
<div onClickCapture={onClick}>
|
||||
<button disabled={true}><span /></button>
|
||||
</div>
|
||||
);
|
||||
var child = ReactDOM.findDOMNode(element).querySelector('span');
|
||||
|
||||
ReactTestUtils.SimulateNative.click(child);
|
||||
expect(onClick.mock.calls.length).toBe(1);
|
||||
});
|
||||
|
||||
it('triggers captured click events for children of disabled elements', function() {
|
||||
var element = ReactTestUtils.renderIntoDocument(
|
||||
<button disabled={true}><span onClickCapture={onClick} /></button>
|
||||
);
|
||||
var child = ReactDOM.findDOMNode(element).querySelector('span');
|
||||
|
||||
ReactTestUtils.SimulateNative.click(child);
|
||||
expect(onClick.mock.calls.length).toBe(1);
|
||||
});
|
||||
@@ -124,10 +165,6 @@ describe('SimpleEventPlugin', function() {
|
||||
describe('iOS bubbling click fix', function() {
|
||||
// See http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
|
||||
|
||||
beforeEach(function() {
|
||||
onClick.mockClear();
|
||||
});
|
||||
|
||||
it('does not add a local click to interactive elements', function() {
|
||||
var container = document.createElement('div');
|
||||
|
||||
|
||||
@@ -59,6 +59,31 @@ var getDictionaryKey = function(inst) {
|
||||
return '.' + inst._rootNodeID;
|
||||
};
|
||||
|
||||
function isInteractive(tag) {
|
||||
return (
|
||||
tag === 'button' || tag === 'input' ||
|
||||
tag === 'select' || tag === 'textarea'
|
||||
);
|
||||
}
|
||||
|
||||
function shouldPreventMouseEvent(name, type, props) {
|
||||
switch (name) {
|
||||
case 'onClick':
|
||||
case 'onClickCapture':
|
||||
case 'onDoubleClick':
|
||||
case 'onDoubleClickCapture':
|
||||
case 'onMouseDown':
|
||||
case 'onMouseDownCapture':
|
||||
case 'onMouseMove':
|
||||
case 'onMouseMoveCapture':
|
||||
case 'onMouseUp':
|
||||
case 'onMouseUpCapture':
|
||||
return !!(props.disabled && isInteractive(type));
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a unified interface for event plugins to be installed and configured.
|
||||
*
|
||||
@@ -133,7 +158,12 @@ var EventPluginHub = {
|
||||
* @return {?function} The stored callback.
|
||||
*/
|
||||
getListener: function(inst, registrationName) {
|
||||
// TODO: shouldPreventMouseEvent is DOM-specific and definitely should not
|
||||
// live here; needs to be moved to a better place soon
|
||||
var bankForRegistrationName = listenerBank[registrationName];
|
||||
if (shouldPreventMouseEvent(registrationName, inst._currentElement.type, inst._currentElement.props)) {
|
||||
return null;
|
||||
}
|
||||
var key = getDictionaryKey(inst);
|
||||
return bankForRegistrationName && bankForRegistrationName[key];
|
||||
},
|
||||
|
||||
+1
-1
@@ -311,7 +311,7 @@ var CHILD_ID2 = '.0.0.1';
|
||||
|
||||
var idToInstance = {};
|
||||
[GRANDPARENT_ID, PARENT_ID, CHILD_ID, CHILD_ID2].forEach(function(id) {
|
||||
idToInstance[id] = {_rootNodeID: id};
|
||||
idToInstance[id] = {_rootNodeID: id, _currentElement: {}};
|
||||
});
|
||||
|
||||
var three = {
|
||||
|
||||
Reference in New Issue
Block a user