@samitouri / QOS-React-2 / commits / 65490a09e6

Use querySelectorAll instead of getElementsByName in ReactDOMInput.

We've been able to use `querySelectorAll` in all the browsers that we support for some time now, but we haven't been able to test code that uses it in the older version of `jsdom` that we were using, until recently. Besides the general goal of modernizing our code, the impetus for this specific change is that I'm trying to support testing without having to render nodes into an actual document. The `.getElementsByName` method is only defined on `document` and only works if the nodes you care about are contained by the document. On the other hand, `querySelectorAll` works on any DOM node, and allows a more precise selection of just the `<input type="radio">` elements that have the appropriate name. IE8's implementation of `querySelectorAll` supports attribute-based selectors, which is all we need here.

Ben Newman committed Jan 29, 2014 at 12:50 UTC 65490a09e63940e68146790e18d847fd351a60ad
1 file changed +10 -3
src/dom/components/ReactDOMInput.js
+10 -3
@@ -130,17 +130,24 @@ var ReactDOMInput = ReactCompositeComponent.createClass({
130 var name = this.props.name;
131 if (this.props.type === 'radio' && name != null) {
132 var rootNode = this.getDOMNode();
133 + var queryRoot = rootNode;
134 +
135 + while (queryRoot.parentNode) {
136 + queryRoot = queryRoot.parentNode;
137 + }
138 +
139 // If `rootNode.form` was non-null, then we could try `form.elements`,
140 // but that sometimes behaves strangely in IE8. We could also try using
141 // `form.getElementsByName`, but that will only return direct children
142 // and won't include inputs that use the HTML5 `form=` attribute. Since
143 // the input might not even be in a form, let's just use the global
138 - // `getElementsByName` to ensure we don't miss anything.
139 - var group = document.getElementsByName(name);
144 + // `querySelectorAll` to ensure we don't miss anything.
145 + var group = queryRoot.querySelectorAll(
146 + 'input[name=' + JSON.stringify('' + name) + '][type="radio"]');
147 +
148 for (var i = 0, groupLen = group.length; i < groupLen; i++) {
149 var otherNode = group[i];
150 if (otherNode === rootNode ||
143 - otherNode.nodeName !== 'INPUT' || otherNode.type !== 'radio' ||
151 otherNode.form !== rootNode.form) {
152 continue;
153 }