+
+ );
+ }
+}
+
+export default InputTestCase;
diff --git a/fixtures/dom/src/components/fixtures/text-inputs/index.js b/fixtures/dom/src/components/fixtures/text-inputs/index.js
index a1683672ce66b..6d6ee9a687db6 100644
--- a/fixtures/dom/src/components/fixtures/text-inputs/index.js
+++ b/fixtures/dom/src/components/fixtures/text-inputs/index.js
@@ -1,62 +1,92 @@
const React = window.React;
+import Fixture from '../../Fixture';
+import FixtureSet from '../../FixtureSet';
+import TestCase from '../../TestCase';
+import InputTestCase from './InputTestCase';
+
class TextInputFixtures extends React.Component {
- state = {
- color: '#ffaaee',
- };
+ render() {
+ return (
+
+
+
+
Move the cursor to after "2" in the text field
+
Type ".2" into the text input
+
- renderControlled = (type) => {
- let id = `controlled_${type}`;
+
+ The text field's value should not update.
+
- let onChange = e => {
- let value = e.target.value;
- if (type === 'number') {
- value = value === '' ? '' : parseFloat(value, 10) || 0;
- }
- this.setState({
- [type] : value,
- });
- };
+
+
+
- let state = this.state[type] || '';
+
+
+
- return (
-
-
-
- → {JSON.stringify(state)}
-
- );
- }
+
+ This issue was first introduced when we added extra logic
+ to number inputs to prevent unexpected behavior in Chrome
+ and Safari (see the number input test case).
+
+
- renderUncontrolled = (type) => {
- let id = `uncontrolled_${type}`;
- return (
-
-
-
-
- );
- }
+
+
+
Type "user@example.com"
+
Select "@"
+
Type ".", to replace "@" with a period
+
- render() {
- // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input
- let types = [
- 'text', 'email', 'number', 'url', 'tel',
- 'color', 'date', 'datetime-local',
- 'time', 'month', 'week', 'range', 'password',
- ];
- return (
-
+
+ The text field's cursor should not jump to the end.
+
+
+
+
+
+
+
+
Type "http://www.example.com"
+
Select "www."
+
Press backspace/delete
+
+
+
+ The text field's cursor should not jump to the end.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
);
}
}
diff --git a/scripts/fiber/tests-passing.txt b/scripts/fiber/tests-passing.txt
index 02bc0a8cb8573..01cba63cf1284 100644
--- a/scripts/fiber/tests-passing.txt
+++ b/scripts/fiber/tests-passing.txt
@@ -1452,6 +1452,9 @@ src/renderers/dom/shared/wrappers/__tests__/ReactDOMInput-test.js
* should properly control a value even if no event listener exists
* should control a value in reentrant events
* should control values in reentrant events with different targets
+* does change the number 2 to "2.0" with no change handler
+* does change the string "2" to "2.0" with no change handler
+* changes the number 2 to "2.0" using a change handler
* should display `defaultValue` of number 0
* only assigns defaultValue if it changes
* should display "true" for `defaultValue` of `true`
@@ -1671,6 +1674,7 @@ src/renderers/shared/fiber/__tests__/ReactIncremental-test.js
* can deprioritize a tree from without dropping work
* can resume work in a subtree even when a parent bails out
* can resume work in a bailed subtree within one pass
+* can resume mounting a class component
* can reuse work done after being preempted
* can reuse work that began but did not complete, after being preempted
* can reuse work if shouldComponentUpdate is false, after being preempted
diff --git a/src/renderers/dom/fiber/wrappers/ReactDOMFiberInput.js b/src/renderers/dom/fiber/wrappers/ReactDOMFiberInput.js
index ebc9812077ea2..41de9687e429d 100644
--- a/src/renderers/dom/fiber/wrappers/ReactDOMFiberInput.js
+++ b/src/renderers/dom/fiber/wrappers/ReactDOMFiberInput.js
@@ -209,8 +209,7 @@ var ReactDOMInput = {
// browsers typically do this as necessary, jsdom doesn't.
node.value = '' + value;
}
- // eslint-disable-next-line
- } else if (value != node.value) {
+ } else if (node.value !== value) {
// Cast `value` to a string to ensure the value is set correctly. While
// browsers typically do this as necessary, jsdom doesn't.
node.value = '' + value;
diff --git a/src/renderers/dom/shared/wrappers/__tests__/ReactDOMInput-test.js b/src/renderers/dom/shared/wrappers/__tests__/ReactDOMInput-test.js
index 16b2fba74814a..19a38b9e182f5 100644
--- a/src/renderers/dom/shared/wrappers/__tests__/ReactDOMInput-test.js
+++ b/src/renderers/dom/shared/wrappers/__tests__/ReactDOMInput-test.js
@@ -179,6 +179,60 @@ describe('ReactDOMInput', () => {
document.body.removeChild(container);
});
+ describe('switching text inputs between numeric and string numbers', () => {
+ it('does change the number 2 to "2.0" with no change handler', () => {
+ var stub = ;
+ stub = ReactTestUtils.renderIntoDocument(stub);
+ var node = ReactDOM.findDOMNode(stub);
+
+ node.value = '2.0';
+
+ ReactTestUtils.Simulate.change(stub);
+
+ expect(node.getAttribute('value')).toBe('2');
+ expect(node.value).toBe('2');
+ });
+
+ it('does change the string "2" to "2.0" with no change handler', () => {
+ var stub = ;
+ stub = ReactTestUtils.renderIntoDocument(stub);
+ var node = ReactDOM.findDOMNode(stub);
+
+ node.value = '2.0';
+
+ ReactTestUtils.Simulate.change(stub);
+
+ expect(node.getAttribute('value')).toBe('2');
+ expect(node.value).toBe('2');
+ });
+
+ it('changes the number 2 to "2.0" using a change handler', () => {
+ class Stub extends React.Component {
+ state = {
+ value: 2,
+ };
+ onChange = event => {
+ this.setState({value: event.target.value});
+ };
+ render() {
+ const {value} = this.state;
+
+ return ;
+ }
+ }
+
+ var stub = ReactTestUtils.renderIntoDocument();
+ var node = ReactDOM.findDOMNode(stub);
+
+ node.value = '2.0';
+
+ ReactTestUtils.Simulate.change(node);
+
+ expect(node.getAttribute('value')).toBe('2.0');
+ expect(node.value).toBe('2.0');
+ });
+ });
+
it('should display `defaultValue` of number 0', () => {
var stub = ;
stub = ReactTestUtils.renderIntoDocument(stub);
@@ -434,7 +488,7 @@ describe('ReactDOMInput', () => {
node.value = '0.0';
ReactTestUtils.Simulate.change(node, {target: {value: '0.0'}});
- expect(node.value).toBe('0.0');
+ expect(node.value).toBe('0');
});
it('should properly control 0.0 for a number input', () => {
diff --git a/src/renderers/dom/stack/client/wrappers/ReactDOMInput.js b/src/renderers/dom/stack/client/wrappers/ReactDOMInput.js
index 15c98554b4578..b05ca82b352db 100644
--- a/src/renderers/dom/stack/client/wrappers/ReactDOMInput.js
+++ b/src/renderers/dom/stack/client/wrappers/ReactDOMInput.js
@@ -201,8 +201,7 @@ var ReactDOMInput = {
// browsers typically do this as necessary, jsdom doesn't.
node.value = '' + value;
}
- // eslint-disable-next-line
- } else if (value != node.value) {
+ } else if (node.value !== value) {
// Cast `value` to a string to ensure the value is set correctly. While
// browsers typically do this as necessary, jsdom doesn't.
node.value = '' + value;