mirror of
https://github.com/zebrajr/react.git
synced 2025-12-06 12:20:20 +01:00
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:
parent
c1833b4b7e
commit
0b220d0f04
|
|
@ -3,12 +3,13 @@
|
|||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"react-scripts": "0.9.5"
|
||||
"react-scripts": "1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"classnames": "^2.2.5",
|
||||
"query-string": "^4.2.3",
|
||||
"core-js": "^2.4.1",
|
||||
"prop-types": "^15.5.6",
|
||||
"query-string": "^4.2.3",
|
||||
"react": "^15.4.1",
|
||||
"react-dom": "^15.4.1",
|
||||
"semver": "^5.3.0"
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@
|
|||
-->
|
||||
<title>React App</title>
|
||||
<script src="https://unpkg.com/prop-types@15.5.6/prop-types.js"></script>
|
||||
<script src="react-loader.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
|
|
|||
43
fixtures/dom/public/react-loader.js
vendored
43
fixtures/dom/public/react-loader.js
vendored
|
|
@ -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>');
|
||||
}
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
const React = window.React;
|
||||
import Header from './Header';
|
||||
import Fixtures from './fixtures';
|
||||
|
||||
import '../style.css';
|
||||
|
||||
const React = window.React;
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
const React = window.React;
|
||||
|
||||
import FixtureSet from '../../FixtureSet';
|
||||
import TestCase from '../../TestCase';
|
||||
|
||||
const React = window.React;
|
||||
|
||||
function onButtonClick() {
|
||||
window.alert(`This shouldn't have happened!`);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
const React = window.React;
|
||||
|
||||
import FixtureSet from '../../FixtureSet';
|
||||
import TestCase from '../../TestCase';
|
||||
|
||||
const React = window.React;
|
||||
|
||||
function BadRender(props) {
|
||||
throw props.error;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
const React = window.React;
|
||||
import RangeInputFixtures from './range-inputs';
|
||||
import TextInputFixtures from './text-inputs';
|
||||
import SelectFixtures from './selects';
|
||||
|
|
@ -10,6 +9,8 @@ import ButtonFixtures from './buttons';
|
|||
import DateInputFixtures from './date-inputs';
|
||||
import ErrorHandling from './error-handling';
|
||||
|
||||
const React = window.React;
|
||||
|
||||
/**
|
||||
* A simple routing component that renders the appropriate
|
||||
* fixture based on the location pathname.
|
||||
|
|
@ -41,4 +42,4 @@ function FixturesPage() {
|
|||
}
|
||||
}
|
||||
|
||||
module.exports = FixturesPage;
|
||||
export default FixturesPage;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
const React = window.React;
|
||||
|
||||
import Fixture from '../../Fixture';
|
||||
|
||||
const React = window.React;
|
||||
|
||||
class NumberInputDecimal extends React.Component {
|
||||
state = {value: '.98'};
|
||||
changeValue = () => {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
const React = window.React;
|
||||
|
||||
import Fixture from '../../Fixture';
|
||||
|
||||
const React = window.React;
|
||||
|
||||
class NumberInputExtraZeroes extends React.Component {
|
||||
state = {value: '3.0000'};
|
||||
changeValue = () => {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
const React = window.React;
|
||||
|
||||
import Fixture from '../../Fixture';
|
||||
|
||||
const React = window.React;
|
||||
|
||||
class NumberTestCase extends React.Component {
|
||||
state = {value: ''};
|
||||
onChange = event => {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
const React = window.React;
|
||||
|
||||
import FixtureSet from '../../FixtureSet';
|
||||
import TestCase from '../../TestCase';
|
||||
import NumberTestCase from './NumberTestCase';
|
||||
import NumberInputDecimal from './NumberInputDecimal';
|
||||
import NumberInputExtraZeroes from './NumberInputExtraZeroes';
|
||||
|
||||
const React = window.React;
|
||||
|
||||
function NumberInputs() {
|
||||
return (
|
||||
<FixtureSet
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
const React = window.React;
|
||||
|
||||
import Fixture from '../../Fixture';
|
||||
|
||||
const React = window.React;
|
||||
|
||||
class PasswordTestCase extends React.Component {
|
||||
state = {value: ''};
|
||||
onChange = event => {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
const React = window.React;
|
||||
|
||||
import FixtureSet from '../../FixtureSet';
|
||||
import TestCase from '../../TestCase';
|
||||
import PasswordTestCase from './PasswordTestCase';
|
||||
|
||||
const React = window.React;
|
||||
|
||||
function NumberInputs() {
|
||||
return (
|
||||
<FixtureSet title="Password inputs" description="">
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
const React = window.React;
|
||||
|
||||
import Fixture from '../../Fixture';
|
||||
const React = window.React;
|
||||
|
||||
class InputTestCase extends React.Component {
|
||||
static defaultProps = {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
const React = window.React;
|
||||
|
||||
import Fixture from '../../Fixture';
|
||||
import FixtureSet from '../../FixtureSet';
|
||||
import TestCase from '../../TestCase';
|
||||
import InputTestCase from './InputTestCase';
|
||||
|
||||
const React = window.React;
|
||||
|
||||
class TextInputFixtures extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
|
|
@ -93,4 +93,4 @@ class TextInputFixtures extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
module.exports = TextInputFixtures;
|
||||
export default TextInputFixtures;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
const React = window.React;
|
||||
const ReactDOM = window.ReactDOM;
|
||||
import App from './components/App';
|
||||
import './polyfills';
|
||||
import loadReact from './react-loader';
|
||||
|
||||
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')
|
||||
);
|
||||
});
|
||||
|
|
|
|||
35
fixtures/dom/src/polyfills.js
Normal file
35
fixtures/dom/src/polyfills.js
Normal 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
63
fixtures/dom/src/react-loader.js
vendored
Normal 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;
|
||||
}
|
||||
|
|
@ -1472,7 +1472,7 @@ core-js@^1.0.0:
|
|||
version "1.2.7"
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e"
|
||||
|
||||
|
|
|
|||
|
|
@ -11,17 +11,14 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
var EventPluginHub = require('EventPluginHub');
|
||||
var EventPropagators = require('EventPropagators');
|
||||
var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');
|
||||
var ReactControlledComponent = require('ReactControlledComponent');
|
||||
var ReactDOMComponentTree = require('ReactDOMComponentTree');
|
||||
var ReactGenericBatching = require('ReactGenericBatching');
|
||||
var SyntheticEvent = require('SyntheticEvent');
|
||||
var getActiveElement = require('fbjs/lib/getActiveElement');
|
||||
|
||||
var inputValueTracking = require('inputValueTracking');
|
||||
var getEventTarget = require('getEventTarget');
|
||||
var isEventSupported = require('isEventSupported');
|
||||
var isTextInputElement = require('isTextInputElement');
|
||||
|
||||
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) {
|
||||
var event = SyntheticEvent.getPooled(
|
||||
eventTypes.change,
|
||||
|
|
@ -56,174 +60,53 @@ function createAndAccumulateChangeEvent(inst, nativeEvent, target) {
|
|||
EventPropagators.accumulateTwoPhaseDispatches(event);
|
||||
return event;
|
||||
}
|
||||
/**
|
||||
* For IE shims
|
||||
*/
|
||||
var activeElement = null;
|
||||
var activeElementInst = null;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
function getInstIfValueChanged(targetInst, targetNode) {
|
||||
if (inputValueTracking.updateValueIfChanged(targetNode)) {
|
||||
return targetInst;
|
||||
}
|
||||
}
|
||||
|
||||
function getTargetInstForChangeEvent(topLevelType, targetInst) {
|
||||
if (topLevelType === 'topChange') {
|
||||
return targetInst;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* SECTION: handle `input` event
|
||||
*/
|
||||
var isInputEventSupported = false;
|
||||
|
||||
var isTextInputEventSupported = false;
|
||||
if (ExecutionEnvironment.canUseDOM) {
|
||||
// IE9 claims to support the input event but fails to trigger it when
|
||||
// deleting text, so we ignore its input events.
|
||||
isInputEventSupported =
|
||||
isEventSupported('input') &&
|
||||
(!document.documentMode || document.documentMode > 9);
|
||||
isTextInputEventSupported =
|
||||
!document.documentMode || document.documentMode > 9;
|
||||
}
|
||||
|
||||
/**
|
||||
* (For IE <=9) Starts tracking propertychange events on the passed-in element
|
||||
* and override the value property so that we can distinguish user events from
|
||||
* value changes in JS.
|
||||
*/
|
||||
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) {
|
||||
function getTargetInstForInputEventPolyfill(
|
||||
topLevelType,
|
||||
targetInst,
|
||||
targetNode,
|
||||
) {
|
||||
if (
|
||||
topLevelType === 'topInput' ||
|
||||
topLevelType === 'topChange' ||
|
||||
// These events catch anything the IE9 onInput misses
|
||||
topLevelType === 'topSelectionChange' ||
|
||||
topLevelType === 'topKeyUp' ||
|
||||
topLevelType === 'topKeyDown'
|
||||
) {
|
||||
// On the selectionchange event, the target is just document which isn't
|
||||
// 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);
|
||||
return getInstIfValueChanged(targetInst, targetNode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* SECTION: handle `click` event
|
||||
*/
|
||||
function shouldUseClickEvent(elem) {
|
||||
// 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) {
|
||||
function getTargetInstForInputOrChangeEvent(
|
||||
topLevelType,
|
||||
targetInst,
|
||||
targetNode,
|
||||
) {
|
||||
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 = {
|
||||
eventTypes: eventTypes,
|
||||
|
||||
_isInputEventSupported: isInputEventSupported,
|
||||
|
||||
extractEvents: function(
|
||||
topLevelType,
|
||||
targetInst,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
) {
|
||||
extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
|
||||
var targetNode = targetInst
|
||||
? ReactDOMComponentTree.getNodeFromInstance(targetInst)
|
||||
: 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;
|
||||
|
||||
if (shouldUseChangeEvent(targetNode)) {
|
||||
getTargetInstFunc = getTargetInstForChangeEvent;
|
||||
} else if (isTextInputElement(targetNode)) {
|
||||
if (isInputEventSupported) {
|
||||
getTargetInstFunc = getTargetInstForInputOrChangeEvent;
|
||||
} else {
|
||||
} else if (isTextInputElement(targetNode) && !isTextInputEventSupported) {
|
||||
getTargetInstFunc = getTargetInstForInputEventPolyfill;
|
||||
handleEventFunc = handleEventsForInputEventPolyfill;
|
||||
}
|
||||
} else if (shouldUseClickEvent(targetNode)) {
|
||||
getTargetInstFunc = getTargetInstForClickEvent;
|
||||
} else {
|
||||
getTargetInstFunc = getTargetInstForInputOrChangeEvent;
|
||||
}
|
||||
|
||||
if (getTargetInstFunc) {
|
||||
var inst = getTargetInstFunc(topLevelType, targetInst);
|
||||
var inst = getTargetInstFunc(topLevelType, targetInst, targetNode);
|
||||
if (inst) {
|
||||
var event = createAndAccumulateChangeEvent(
|
||||
inst,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ var React = require('react');
|
|||
var ReactDOM = require('react-dom');
|
||||
var ReactTestUtils = require('react-dom/test-utils');
|
||||
// TODO: can we express this test with only public API?
|
||||
var ChangeEventPlugin = require('ChangeEventPlugin');
|
||||
var inputValueTracking = require('inputValueTracking');
|
||||
|
||||
function getTrackedValue(elem) {
|
||||
|
|
@ -54,7 +53,7 @@ describe('ChangeEventPlugin', () => {
|
|||
);
|
||||
|
||||
setUntrackedValue(input, true);
|
||||
ReactTestUtils.SimulateNative.click(input);
|
||||
ReactTestUtils.SimulateNative.change(input);
|
||||
|
||||
expect(called).toBe(1);
|
||||
});
|
||||
|
|
@ -103,12 +102,12 @@ describe('ChangeEventPlugin', () => {
|
|||
);
|
||||
|
||||
input.checked = true;
|
||||
ReactTestUtils.SimulateNative.click(input);
|
||||
ReactTestUtils.SimulateNative.change(input);
|
||||
expect(called).toBe(0);
|
||||
|
||||
input.checked = false;
|
||||
setTrackedValue(input, undefined);
|
||||
ReactTestUtils.SimulateNative.click(input);
|
||||
ReactTestUtils.SimulateNative.change(input);
|
||||
|
||||
expect(called).toBe(1);
|
||||
});
|
||||
|
|
@ -131,8 +130,8 @@ describe('ChangeEventPlugin', () => {
|
|||
<input type="radio" onChange={cb} />,
|
||||
);
|
||||
setUntrackedValue(input, true);
|
||||
ReactTestUtils.SimulateNative.click(input);
|
||||
ReactTestUtils.SimulateNative.click(input);
|
||||
ReactTestUtils.SimulateNative.change(input);
|
||||
ReactTestUtils.SimulateNative.input(input);
|
||||
expect(called).toBe(1);
|
||||
});
|
||||
|
||||
|
|
@ -182,10 +181,6 @@ describe('ChangeEventPlugin', () => {
|
|||
expect(e.type).toBe('change');
|
||||
}
|
||||
|
||||
if (!ChangeEventPlugin._isInputEventSupported) {
|
||||
return;
|
||||
}
|
||||
|
||||
var input = ReactTestUtils.renderIntoDocument(
|
||||
<input type="range" onChange={cb} />,
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user