diff --git a/fixtures/dom/src/components/fixtures/text-inputs/index.js b/fixtures/dom/src/components/fixtures/text-inputs/index.js index 61600b8ca1eb..9f98a00a9be1 100644 --- a/fixtures/dom/src/components/fixtures/text-inputs/index.js +++ b/fixtures/dom/src/components/fixtures/text-inputs/index.js @@ -70,6 +70,22 @@ class TextInputFixtures extends React.Component { + + +
  • Type any character
  • +
    + + + There should be no errors in the console. + + +
    +
    + +
    +
    +
    + diff --git a/src/renderers/dom/shared/ReactInputSelection.js b/src/renderers/dom/shared/ReactInputSelection.js index 427e71f88a79..7d172c979e0a 100644 --- a/src/renderers/dom/shared/ReactInputSelection.js +++ b/src/renderers/dom/shared/ReactInputSelection.js @@ -22,6 +22,9 @@ function isInDocument(node) { return containsNode(document.documentElement, node); } +var nodeNameGetter = Object.getOwnPropertyDescriptor(Node.prototype, 'nodeName') + .get; + /** * @ReactInputSelection: React input selection module. Based on Selection.js, * but modified to be suitable for react and has a couple of bug fixes (doesn't @@ -30,12 +33,16 @@ function isInDocument(node) { */ var ReactInputSelection = { hasSelectionCapabilities: function(elem) { - var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase(); + if (elem === window) { + return false; + } + + var nodeName = nodeNameGetter.call(elem); + return ( - nodeName && - ((nodeName === 'input' && elem.type === 'text') || - nodeName === 'textarea' || - elem.contentEditable === 'true') + (nodeName === 'INPUT' && elem.type === 'text') || + nodeName === 'TEXTAREA' || + elem.contentEditable === 'true' ); }, diff --git a/src/renderers/dom/shared/eventPlugins/ChangeEventPlugin.js b/src/renderers/dom/shared/eventPlugins/ChangeEventPlugin.js index 6381eb54eded..567148764d35 100644 --- a/src/renderers/dom/shared/eventPlugins/ChangeEventPlugin.js +++ b/src/renderers/dom/shared/eventPlugins/ChangeEventPlugin.js @@ -40,10 +40,18 @@ var eventTypes = { }, }; +var nodeNameGetter = Object.getOwnPropertyDescriptor(Node.prototype, 'nodeName') + .get; + function shouldUseChangeEvent(elem) { - var nodeName = elem.nodeName && elem.nodeName.toLowerCase(); + if (elem === window) { + return false; + } + + var nodeName = nodeNameGetter.call(elem); + return ( - nodeName === 'select' || (nodeName === 'input' && elem.type === 'file') + nodeName === 'SELECT' || (nodeName === 'INPUT' && elem.type === 'FILE') ); } @@ -159,7 +167,6 @@ var ChangeEventPlugin = { } var getTargetInstFunc, handleEventFunc; - if (shouldUseChangeEvent(targetNode)) { getTargetInstFunc = getTargetInstForChangeEvent; } else if (isTextInputElement(targetNode) && !isTextInputEventSupported) { diff --git a/src/renderers/dom/shared/wrappers/__tests__/ReactDOMInput-test.js b/src/renderers/dom/shared/wrappers/__tests__/ReactDOMInput-test.js index b90923c77213..d08c6459aaf1 100644 --- a/src/renderers/dom/shared/wrappers/__tests__/ReactDOMInput-test.js +++ b/src/renderers/dom/shared/wrappers/__tests__/ReactDOMInput-test.js @@ -1346,4 +1346,26 @@ describe('ReactDOMInput', () => { expect(node.getAttribute('value')).toBe('1'); }); }); + + it('an input with an id of `nodeName` works as intended', () => { + var spy = jest.fn(); + + class Test extends React.Component { + render() { + return ( +
    + + +
    + ); + } + } + + var stub = ReactTestUtils.renderIntoDocument(); + var node = ReactDOM.findDOMNode(stub); + + ReactTestUtils.Simulate.submit(node); + + expect(spy).toHaveBeenCalled(); + }); }); diff --git a/src/renderers/shared/utils/isTextInputElement.js b/src/renderers/shared/utils/isTextInputElement.js index 633c19ce33af..61f5ba03819e 100644 --- a/src/renderers/shared/utils/isTextInputElement.js +++ b/src/renderers/shared/utils/isTextInputElement.js @@ -34,13 +34,11 @@ var supportedInputTypes: {[key: string]: true | void} = { }; function isTextInputElement(elem: ?HTMLElement): boolean { - var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase(); - - if (nodeName === 'input') { + if (elem instanceof HTMLInputElement) { return !!supportedInputTypes[((elem: any): HTMLInputElement).type]; } - if (nodeName === 'textarea') { + if (elem instanceof HTMLTextAreaElement) { return true; }