Remove old IE polyfill code (#10238)

* Upgrade DOM Fixtures

Upgrade to react-scripts v1 and include required polyfills for older
browsers

* Remove ChangeEvent polyfills for unsupported browsers
This commit is contained in:
Jason Quense 2017-08-03 08:45:41 -04:00 committed by Dan Abramov
parent c1833b4b7e
commit 0b220d0f04
21 changed files with 193 additions and 255 deletions

View File

@ -3,12 +3,13 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"devDependencies": { "devDependencies": {
"react-scripts": "0.9.5" "react-scripts": "1.0.0"
}, },
"dependencies": { "dependencies": {
"classnames": "^2.2.5", "classnames": "^2.2.5",
"query-string": "^4.2.3", "core-js": "^2.4.1",
"prop-types": "^15.5.6", "prop-types": "^15.5.6",
"query-string": "^4.2.3",
"react": "^15.4.1", "react": "^15.4.1",
"react-dom": "^15.4.1", "react-dom": "^15.4.1",
"semver": "^5.3.0" "semver": "^5.3.0"

View File

@ -15,7 +15,6 @@
--> -->
<title>React App</title> <title>React App</title>
<script src="https://unpkg.com/prop-types@15.5.6/prop-types.js"></script> <script src="https://unpkg.com/prop-types@15.5.6/prop-types.js"></script>
<script src="react-loader.js"></script>
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>

View File

@ -1,43 +0,0 @@
/**
* Take a version from the window query string and load a specific
* version of React.
*
* @example
* http://localhost:3000?version=15.4.1
* (Loads React 15.4.1)
*/
var REACT_PATH = 'react.development.js';
var DOM_PATH = 'react-dom.development.js';
function parseQuery(qstr) {
var query = {};
var a = qstr.substr(1).split('&');
for (var i = 0; i < a.length; i++) {
var b = a[i].split('=');
query[decodeURIComponent(b[0])] = decodeURIComponent(b[1] || '');
}
return query;
}
var query = parseQuery(window.location.search);
var version = query.version || 'local';
if (version !== 'local') {
REACT_PATH = 'https://unpkg.com/react@' + version + '/dist/react.js';
DOM_PATH = 'https://unpkg.com/react-dom@' + version + '/dist/react-dom.js';
}
document.write('<script src="' + REACT_PATH + '"></script>');
// Versions earlier than 14 do not use ReactDOM
if (version === 'local' || parseFloat(version, 10) > 0.13) {
document.write('<script src="' + DOM_PATH + '"></script>');
} else {
// Aliasing React to ReactDOM for compatibility.
document.write('<script>ReactDOM = React</script>');
}

View File

@ -1,9 +1,9 @@
const React = window.React;
import Header from './Header'; import Header from './Header';
import Fixtures from './fixtures'; import Fixtures from './fixtures';
import '../style.css'; import '../style.css';
const React = window.React;
function App() { function App() {
return ( return (
<div> <div>

View File

@ -1,8 +1,8 @@
const React = window.React;
import FixtureSet from '../../FixtureSet'; import FixtureSet from '../../FixtureSet';
import TestCase from '../../TestCase'; import TestCase from '../../TestCase';
const React = window.React;
function onButtonClick() { function onButtonClick() {
window.alert(`This shouldn't have happened!`); window.alert(`This shouldn't have happened!`);
} }

View File

@ -1,8 +1,8 @@
const React = window.React;
import FixtureSet from '../../FixtureSet'; import FixtureSet from '../../FixtureSet';
import TestCase from '../../TestCase'; import TestCase from '../../TestCase';
const React = window.React;
function BadRender(props) { function BadRender(props) {
throw props.error; throw props.error;
} }

View File

@ -1,4 +1,3 @@
const React = window.React;
import RangeInputFixtures from './range-inputs'; import RangeInputFixtures from './range-inputs';
import TextInputFixtures from './text-inputs'; import TextInputFixtures from './text-inputs';
import SelectFixtures from './selects'; import SelectFixtures from './selects';
@ -10,6 +9,8 @@ import ButtonFixtures from './buttons';
import DateInputFixtures from './date-inputs'; import DateInputFixtures from './date-inputs';
import ErrorHandling from './error-handling'; import ErrorHandling from './error-handling';
const React = window.React;
/** /**
* A simple routing component that renders the appropriate * A simple routing component that renders the appropriate
* fixture based on the location pathname. * fixture based on the location pathname.
@ -41,4 +42,4 @@ function FixturesPage() {
} }
} }
module.exports = FixturesPage; export default FixturesPage;

View File

@ -1,7 +1,7 @@
const React = window.React;
import Fixture from '../../Fixture'; import Fixture from '../../Fixture';
const React = window.React;
class NumberInputDecimal extends React.Component { class NumberInputDecimal extends React.Component {
state = {value: '.98'}; state = {value: '.98'};
changeValue = () => { changeValue = () => {

View File

@ -1,7 +1,7 @@
const React = window.React;
import Fixture from '../../Fixture'; import Fixture from '../../Fixture';
const React = window.React;
class NumberInputExtraZeroes extends React.Component { class NumberInputExtraZeroes extends React.Component {
state = {value: '3.0000'}; state = {value: '3.0000'};
changeValue = () => { changeValue = () => {

View File

@ -1,7 +1,7 @@
const React = window.React;
import Fixture from '../../Fixture'; import Fixture from '../../Fixture';
const React = window.React;
class NumberTestCase extends React.Component { class NumberTestCase extends React.Component {
state = {value: ''}; state = {value: ''};
onChange = event => { onChange = event => {

View File

@ -1,11 +1,11 @@
const React = window.React;
import FixtureSet from '../../FixtureSet'; import FixtureSet from '../../FixtureSet';
import TestCase from '../../TestCase'; import TestCase from '../../TestCase';
import NumberTestCase from './NumberTestCase'; import NumberTestCase from './NumberTestCase';
import NumberInputDecimal from './NumberInputDecimal'; import NumberInputDecimal from './NumberInputDecimal';
import NumberInputExtraZeroes from './NumberInputExtraZeroes'; import NumberInputExtraZeroes from './NumberInputExtraZeroes';
const React = window.React;
function NumberInputs() { function NumberInputs() {
return ( return (
<FixtureSet <FixtureSet

View File

@ -1,7 +1,7 @@
const React = window.React;
import Fixture from '../../Fixture'; import Fixture from '../../Fixture';
const React = window.React;
class PasswordTestCase extends React.Component { class PasswordTestCase extends React.Component {
state = {value: ''}; state = {value: ''};
onChange = event => { onChange = event => {

View File

@ -1,9 +1,9 @@
const React = window.React;
import FixtureSet from '../../FixtureSet'; import FixtureSet from '../../FixtureSet';
import TestCase from '../../TestCase'; import TestCase from '../../TestCase';
import PasswordTestCase from './PasswordTestCase'; import PasswordTestCase from './PasswordTestCase';
const React = window.React;
function NumberInputs() { function NumberInputs() {
return ( return (
<FixtureSet title="Password inputs" description=""> <FixtureSet title="Password inputs" description="">

View File

@ -1,6 +1,5 @@
const React = window.React;
import Fixture from '../../Fixture'; import Fixture from '../../Fixture';
const React = window.React;
class InputTestCase extends React.Component { class InputTestCase extends React.Component {
static defaultProps = { static defaultProps = {

View File

@ -1,10 +1,10 @@
const React = window.React;
import Fixture from '../../Fixture'; import Fixture from '../../Fixture';
import FixtureSet from '../../FixtureSet'; import FixtureSet from '../../FixtureSet';
import TestCase from '../../TestCase'; import TestCase from '../../TestCase';
import InputTestCase from './InputTestCase'; import InputTestCase from './InputTestCase';
const React = window.React;
class TextInputFixtures extends React.Component { class TextInputFixtures extends React.Component {
render() { render() {
return ( return (
@ -93,4 +93,4 @@ class TextInputFixtures extends React.Component {
} }
} }
module.exports = TextInputFixtures; export default TextInputFixtures;

View File

@ -1,5 +1,11 @@
const React = window.React; import './polyfills';
const ReactDOM = window.ReactDOM; import loadReact from './react-loader';
import App from './components/App';
ReactDOM.render(<App />, document.getElementById('root')); loadReact().then(() => import('./components/App')).then(App => {
const {React, ReactDOM} = window;
ReactDOM.render(
React.createElement(App.default),
document.getElementById('root')
);
});

View File

@ -0,0 +1,35 @@
import 'core-js/es6/promise';
import 'core-js/es6/set';
import 'core-js/es6/map';
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
// requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel
// MIT license
(function() {
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
window.cancelAnimationFrame =
window[vendors[x] + 'CancelAnimationFrame'] ||
window[vendors[x] + 'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame)
window.requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() {
callback(currTime + timeToCall);
}, timeToCall);
lastTime = currTime + timeToCall;
return id;
};
if (!window.cancelAnimationFrame)
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
})();

63
fixtures/dom/src/react-loader.js vendored Normal file
View File

@ -0,0 +1,63 @@
/**
* Take a version from the window query string and load a specific
* version of React.
*
* @example
* http://localhost:3000?version=15.4.1
* (Loads React 15.4.1)
*/
function parseQuery(qstr) {
var query = {};
var a = qstr.substr(1).split('&');
for (var i = 0; i < a.length; i++) {
var b = a[i].split('=');
query[decodeURIComponent(b[0])] = decodeURIComponent(b[1] || '');
}
return query;
}
function loadScript(src) {
let firstScript = document.getElementsByTagName('script')[0];
let scriptNode;
return new Promise((resolve, reject) => {
scriptNode = document.createElement('script');
scriptNode.async = 1;
scriptNode.src = src;
scriptNode.onload = () => resolve();
scriptNode.onerror = () => reject(new Error(`failed to load: ${src}`));
firstScript.parentNode.insertBefore(scriptNode, firstScript);
});
}
export default function loadReact() {
let REACT_PATH = 'react.development.js';
let DOM_PATH = 'react-dom.development.js';
let query = parseQuery(window.location.search);
let version = query.version || 'local';
if (version !== 'local') {
REACT_PATH = 'https://unpkg.com/react@' + version + '/dist/react.js';
DOM_PATH = 'https://unpkg.com/react-dom@' + version + '/dist/react-dom.js';
}
const needsReactDOM = version === 'local' || parseFloat(version, 10) > 0.13;
let request = loadScript(REACT_PATH);
if (needsReactDOM) {
request = request.then(() => loadScript(DOM_PATH));
} else {
// Aliasing React to ReactDOM for compatibility.
request = request.then(() => {
window.ReactDOM = window.React;
});
}
return request;
}

View File

@ -1472,7 +1472,7 @@ core-js@^1.0.0:
version "1.2.7" version "1.2.7"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
core-js@^2.4.0: core-js@^2.4.0, core-js@^2.4.1:
version "2.4.1" version "2.4.1"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e"

View File

@ -11,17 +11,14 @@
'use strict'; 'use strict';
var EventPluginHub = require('EventPluginHub');
var EventPropagators = require('EventPropagators'); var EventPropagators = require('EventPropagators');
var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment'); var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');
var ReactControlledComponent = require('ReactControlledComponent'); var ReactControlledComponent = require('ReactControlledComponent');
var ReactDOMComponentTree = require('ReactDOMComponentTree'); var ReactDOMComponentTree = require('ReactDOMComponentTree');
var ReactGenericBatching = require('ReactGenericBatching');
var SyntheticEvent = require('SyntheticEvent'); var SyntheticEvent = require('SyntheticEvent');
var getActiveElement = require('fbjs/lib/getActiveElement');
var inputValueTracking = require('inputValueTracking'); var inputValueTracking = require('inputValueTracking');
var getEventTarget = require('getEventTarget');
var isEventSupported = require('isEventSupported');
var isTextInputElement = require('isTextInputElement'); var isTextInputElement = require('isTextInputElement');
var eventTypes = { var eventTypes = {
@ -43,6 +40,13 @@ var eventTypes = {
}, },
}; };
function shouldUseChangeEvent(elem) {
var nodeName = elem.nodeName && elem.nodeName.toLowerCase();
return (
nodeName === 'select' || (nodeName === 'input' && elem.type === 'file')
);
}
function createAndAccumulateChangeEvent(inst, nativeEvent, target) { function createAndAccumulateChangeEvent(inst, nativeEvent, target) {
var event = SyntheticEvent.getPooled( var event = SyntheticEvent.getPooled(
eventTypes.change, eventTypes.change,
@ -56,174 +60,53 @@ function createAndAccumulateChangeEvent(inst, nativeEvent, target) {
EventPropagators.accumulateTwoPhaseDispatches(event); EventPropagators.accumulateTwoPhaseDispatches(event);
return event; return event;
} }
/**
* For IE shims
*/
var activeElement = null;
var activeElementInst = null;
/** function getInstIfValueChanged(targetInst, targetNode) {
* SECTION: handle `change` event
*/
function shouldUseChangeEvent(elem) {
var nodeName = elem.nodeName && elem.nodeName.toLowerCase();
return (
nodeName === 'select' || (nodeName === 'input' && elem.type === 'file')
);
}
function manualDispatchChangeEvent(nativeEvent) {
var event = createAndAccumulateChangeEvent(
activeElementInst,
nativeEvent,
getEventTarget(nativeEvent),
);
// If change and propertychange bubbled, we'd just bind to it like all the
// other events and have it go through ReactBrowserEventEmitter. Since it
// doesn't, we manually listen for the events and so we have to enqueue and
// process the abstract event manually.
//
// Batching is necessary here in order to ensure that all event handlers run
// before the next rerender (including event handlers attached to ancestor
// elements instead of directly on the input). Without this, controlled
// components don't work properly in conjunction with event bubbling because
// the component is rerendered and the value reverted before all the event
// handlers can run. See https://github.com/facebook/react/issues/708.
ReactGenericBatching.batchedUpdates(runEventInBatch, event);
}
function runEventInBatch(event) {
EventPluginHub.enqueueEvents(event);
EventPluginHub.processEventQueue(false);
}
function getInstIfValueChanged(targetInst) {
const targetNode = ReactDOMComponentTree.getNodeFromInstance(targetInst);
if (inputValueTracking.updateValueIfChanged(targetNode)) { if (inputValueTracking.updateValueIfChanged(targetNode)) {
return targetInst; return targetInst;
} }
} }
function getTargetInstForChangeEvent(topLevelType, targetInst) {
if (topLevelType === 'topChange') {
return targetInst;
}
}
/** /**
* SECTION: handle `input` event * SECTION: handle `input` event
*/ */
var isInputEventSupported = false;
var isTextInputEventSupported = false;
if (ExecutionEnvironment.canUseDOM) { if (ExecutionEnvironment.canUseDOM) {
// IE9 claims to support the input event but fails to trigger it when isTextInputEventSupported =
// deleting text, so we ignore its input events. !document.documentMode || document.documentMode > 9;
isInputEventSupported =
isEventSupported('input') &&
(!document.documentMode || document.documentMode > 9);
} }
/** function getTargetInstForInputEventPolyfill(
* (For IE <=9) Starts tracking propertychange events on the passed-in element topLevelType,
* and override the value property so that we can distinguish user events from targetInst,
* value changes in JS. targetNode,
*/ ) {
function startWatchingForValueChange(target, targetInst) {
activeElement = target;
activeElementInst = targetInst;
activeElement.attachEvent('onpropertychange', handlePropertyChange);
}
/**
* (For IE <=9) Removes the event listeners from the currently-tracked element,
* if any exists.
*/
function stopWatchingForValueChange() {
if (!activeElement) {
return;
}
activeElement.detachEvent('onpropertychange', handlePropertyChange);
activeElement = null;
activeElementInst = null;
}
/**
* (For IE <=9) Handles a propertychange event, sending a `change` event if
* the value of the active element has changed.
*/
function handlePropertyChange(nativeEvent) {
if (nativeEvent.propertyName !== 'value') {
return;
}
if (getInstIfValueChanged(activeElementInst)) {
manualDispatchChangeEvent(nativeEvent);
}
}
function handleEventsForInputEventPolyfill(topLevelType, target, targetInst) {
if (topLevelType === 'topFocus') {
// In IE9, propertychange fires for most input events but is buggy and
// doesn't fire when text is deleted, but conveniently, selectionchange
// appears to fire in all of the remaining cases so we catch those and
// forward the event if the value has changed
// In either case, we don't want to call the event handler if the value
// is changed from JS so we redefine a setter for `.value` that updates
// our activeElementValue variable, allowing us to ignore those changes
//
// stopWatching() should be a noop here but we call it just in case we
// missed a blur event somehow.
stopWatchingForValueChange();
startWatchingForValueChange(target, targetInst);
} else if (topLevelType === 'topBlur') {
stopWatchingForValueChange();
}
}
// For IE8 and IE9.
function getTargetInstForInputEventPolyfill(topLevelType, targetInst) {
if ( if (
topLevelType === 'topInput' ||
topLevelType === 'topChange' ||
// These events catch anything the IE9 onInput misses
topLevelType === 'topSelectionChange' || topLevelType === 'topSelectionChange' ||
topLevelType === 'topKeyUp' || topLevelType === 'topKeyUp' ||
topLevelType === 'topKeyDown' topLevelType === 'topKeyDown'
) { ) {
// On the selectionchange event, the target is just document which isn't return getInstIfValueChanged(targetInst, targetNode);
// helpful for us so just check activeElement instead.
//
// 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
// propertychange on the first input event after setting `value` from a
// script and fires only keydown, keypress, keyup. Catching keyup usually
// gets it and catching keydown lets us fire an event for the first
// keystroke if user does a key repeat (it'll be a little delayed: right
// before the second keystroke). Other input methods (e.g., paste) seem to
// fire selectionchange normally.
return getInstIfValueChanged(activeElementInst);
} }
} }
/** function getTargetInstForInputOrChangeEvent(
* SECTION: handle `click` event topLevelType,
*/ targetInst,
function shouldUseClickEvent(elem) { targetNode,
// Use the `click` event to detect changes to checkbox and radio inputs. ) {
// This approach works across all browsers, whereas `change` does not fire
// until `blur` in IE8.
var nodeName = elem.nodeName;
return (
nodeName &&
nodeName.toLowerCase() === 'input' &&
(elem.type === 'checkbox' || elem.type === 'radio')
);
}
function getTargetInstForClickEvent(topLevelType, targetInst) {
if (topLevelType === 'topClick') {
return getInstIfValueChanged(targetInst);
}
}
function getTargetInstForInputOrChangeEvent(topLevelType, targetInst) {
if (topLevelType === 'topInput' || topLevelType === 'topChange') { if (topLevelType === 'topInput' || topLevelType === 'topChange') {
return getInstIfValueChanged(targetInst); return getInstIfValueChanged(targetInst, targetNode);
}
}
function getTargetInstForChangeEvent(topLevelType, targetInst, targetNode) {
if (topLevelType === 'topChange') {
return getInstIfValueChanged(targetInst, targetNode);
} }
} }
@ -260,34 +143,33 @@ function handleControlledInputBlur(inst, node) {
var ChangeEventPlugin = { var ChangeEventPlugin = {
eventTypes: eventTypes, eventTypes: eventTypes,
_isInputEventSupported: isInputEventSupported, extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
extractEvents: function(
topLevelType,
targetInst,
nativeEvent,
nativeEventTarget,
) {
var targetNode = targetInst var targetNode = targetInst
? ReactDOMComponentTree.getNodeFromInstance(targetInst) ? ReactDOMComponentTree.getNodeFromInstance(targetInst)
: window; : window;
// On the selectionchange event, the target is the document which isn't
// helpful becasue we need the input, so we use the activeElement instead.
if (!isTextInputEventSupported && topLevelType === 'topSelectionChange') {
nativeEventTarget = targetNode = getActiveElement();
if (targetNode) {
targetInst = ReactDOMComponentTree.getInstanceFromNode(targetNode);
}
}
var getTargetInstFunc, handleEventFunc; var getTargetInstFunc, handleEventFunc;
if (shouldUseChangeEvent(targetNode)) { if (shouldUseChangeEvent(targetNode)) {
getTargetInstFunc = getTargetInstForChangeEvent; getTargetInstFunc = getTargetInstForChangeEvent;
} else if (isTextInputElement(targetNode)) { } else if (isTextInputElement(targetNode) && !isTextInputEventSupported) {
if (isInputEventSupported) {
getTargetInstFunc = getTargetInstForInputOrChangeEvent;
} else {
getTargetInstFunc = getTargetInstForInputEventPolyfill; getTargetInstFunc = getTargetInstForInputEventPolyfill;
handleEventFunc = handleEventsForInputEventPolyfill; } else {
} getTargetInstFunc = getTargetInstForInputOrChangeEvent;
} else if (shouldUseClickEvent(targetNode)) {
getTargetInstFunc = getTargetInstForClickEvent;
} }
if (getTargetInstFunc) { if (getTargetInstFunc) {
var inst = getTargetInstFunc(topLevelType, targetInst); var inst = getTargetInstFunc(topLevelType, targetInst, targetNode);
if (inst) { if (inst) {
var event = createAndAccumulateChangeEvent( var event = createAndAccumulateChangeEvent(
inst, inst,

View File

@ -15,7 +15,6 @@ var React = require('react');
var ReactDOM = require('react-dom'); var ReactDOM = require('react-dom');
var ReactTestUtils = require('react-dom/test-utils'); var ReactTestUtils = require('react-dom/test-utils');
// TODO: can we express this test with only public API? // TODO: can we express this test with only public API?
var ChangeEventPlugin = require('ChangeEventPlugin');
var inputValueTracking = require('inputValueTracking'); var inputValueTracking = require('inputValueTracking');
function getTrackedValue(elem) { function getTrackedValue(elem) {
@ -54,7 +53,7 @@ describe('ChangeEventPlugin', () => {
); );
setUntrackedValue(input, true); setUntrackedValue(input, true);
ReactTestUtils.SimulateNative.click(input); ReactTestUtils.SimulateNative.change(input);
expect(called).toBe(1); expect(called).toBe(1);
}); });
@ -103,12 +102,12 @@ describe('ChangeEventPlugin', () => {
); );
input.checked = true; input.checked = true;
ReactTestUtils.SimulateNative.click(input); ReactTestUtils.SimulateNative.change(input);
expect(called).toBe(0); expect(called).toBe(0);
input.checked = false; input.checked = false;
setTrackedValue(input, undefined); setTrackedValue(input, undefined);
ReactTestUtils.SimulateNative.click(input); ReactTestUtils.SimulateNative.change(input);
expect(called).toBe(1); expect(called).toBe(1);
}); });
@ -131,8 +130,8 @@ describe('ChangeEventPlugin', () => {
<input type="radio" onChange={cb} />, <input type="radio" onChange={cb} />,
); );
setUntrackedValue(input, true); setUntrackedValue(input, true);
ReactTestUtils.SimulateNative.click(input); ReactTestUtils.SimulateNative.change(input);
ReactTestUtils.SimulateNative.click(input); ReactTestUtils.SimulateNative.input(input);
expect(called).toBe(1); expect(called).toBe(1);
}); });
@ -182,10 +181,6 @@ describe('ChangeEventPlugin', () => {
expect(e.type).toBe('change'); expect(e.type).toBe('change');
} }
if (!ChangeEventPlugin._isInputEventSupported) {
return;
}
var input = ReactTestUtils.renderIntoDocument( var input = ReactTestUtils.renderIntoDocument(
<input type="range" onChange={cb} />, <input type="range" onChange={cb} />,
); );