diff --git a/packages/react-dom/src/client/__tests__/getNodeForCharacterOffset-test.js b/packages/react-dom/src/client/__tests__/getNodeForCharacterOffset-test.js
index 6df208437f073..6e662d264dfb5 100644
--- a/packages/react-dom/src/client/__tests__/getNodeForCharacterOffset-test.js
+++ b/packages/react-dom/src/client/__tests__/getNodeForCharacterOffset-test.js
@@ -9,74 +9,108 @@
'use strict';
-// TODO: can we express this test with only public API?
-var getNodeForCharacterOffset = require('../getNodeForCharacterOffset').default;
-
-// Create node from HTML string
-function createNode(html) {
- var node = (getTestDocument() || document).createElement('div');
- node.innerHTML = html;
- return node;
-}
-
-function getTestDocument(markup) {
- var doc = document.implementation.createHTMLDocument('');
- doc.open();
- doc.write(
- markup ||
- '
test doc',
- );
- doc.close();
- return doc;
-}
-
-// Check getNodeForCharacterOffset return value matches expected result.
-function expectNodeOffset(result, textContent, nodeOffset) {
- expect(result.node.textContent).toBe(textContent);
- expect(result.offset).toBe(nodeOffset);
-}
-
describe('getNodeForCharacterOffset', () => {
- it('should handle siblings', () => {
- var node = createNode('123456789');
+ var React;
+ var ReactDOM;
- expectNodeOffset(getNodeForCharacterOffset(node, 0), '123', 0);
- expectNodeOffset(getNodeForCharacterOffset(node, 4), '456', 1);
+ beforeEach(() => {
+ React = require('react');
+ ReactDOM = require('react-dom');
});
- it('should handle trailing chars', () => {
- var node = createNode('123456789');
+ it('should re-render an input with the same selection', done => {
+ const container = document.createElement('div');
+ let node, component;
+ document.body.appendChild(container);
- expectNodeOffset(getNodeForCharacterOffset(node, 3), '123', 3);
- expectNodeOffset(getNodeForCharacterOffset(node, 9), '789', 3);
- });
+ class InputComponent extends React.Component {
+ constructor(props) {
+ super(props);
- it('should handle trees', () => {
- var node = createNode(
- '' +
- '1' +
- '' +
- '' +
- '2' +
- '' +
- '' +
- '' +
- '' +
- '3' +
- '45' +
- '' +
- '',
- );
-
- expectNodeOffset(getNodeForCharacterOffset(node, 3), '3', 1);
- expectNodeOffset(getNodeForCharacterOffset(node, 5), '45', 2);
- expect(getNodeForCharacterOffset(node, 10)).toBeUndefined();
- });
+ this.state = {
+ oneFirst: true,
+ oneValue: 'foo',
+ twoValue: 'foo',
+ };
+ }
+
+ componentWillMount() {
+ component = this;
+ }
+
+ handleChange(e) {
+ this.setState({value: e.target.value});
+ }
+
+ renderForms() {
+ if (this.state.oneFirst) {
+ return [
+ (node = e)}
+ readOnly={true}
+ />,
+ ,
+ ];
+ } else {
+ return [
+ ,
+ ,
+ ];
+ }
+ }
+
+ render() {
+ return ;
+ }
+ }
+
+ ReactDOM.render(, container);
+
+ node.focus();
+ node.setSelectionRange(1, 1);
+
+ const inputDescriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'selectionStart');
+
+ delete HTMLInputElement.prototype.selectionStart;
+
+ let startMarkerNode, startMarkerOffset;
+ let endMarkerNode, endMarkerOffset;
+
+ // These aren't implemented by jsdom yet, so let's re-implement them
+ // to test the markers created by getNodeForCharacterOffset
+
+ window.getSelection = () => ({
+ removeAllRanges: function() {
+ return true;
+ },
+ addRange: function(range) {},
+ extend: function(endNode, endOffset) {
+ endMarkerNode = endNode;
+ endMarkerOffset = endOffset;
+ },
+ });
- it('should handle non-existent offset', () => {
- var node = createNode('123');
+ document.createRange = () => ({
+ setStart: function(startNode, startOffset) {
+ startMarkerNode = startNode;
+ startMarkerOffset = startOffset;
+ },
+ setEnd: function(endNode, endOffset) {
+ endMarkerNode = endNode;
+ endMarkerOffset = endOffset;
+ },
+ });
- expect(getNodeForCharacterOffset(node, -1)).toBeUndefined();
- expect(getNodeForCharacterOffset(node, 4)).toBeUndefined();
+ try {
+ component.setState({oneFirst: false}, () => {
+ console.log(startMarkerNode, startMarkerOffset);
+ console.log(endMarkerNode, endMarkerOffset);
+ done();
+ });
+ } finally {
+ Object.defineProperty(HTMLInputElement.prototype, 'selectionStart', inputDescriptor);
+ }
});
});