From 99785358222f9d87353332f8fac92244f988bd9f Mon Sep 17 00:00:00 2001 From: Rafael Weinstein Date: Tue, 24 Sep 2013 19:36:56 -0700 Subject: [PATCH] getAssociatedRadioButtons needs to check within the TreeScope https://github.com/Polymer/polymer/issues/291 R=arv Review URL: https://codereview.appspot.com/13889043 --- src/NodeBind.js | 15 ++++++++++++--- tests/tests.js | 28 +++++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/NodeBind.js b/src/NodeBind.js index 88b021c..1729f20 100644 --- a/src/NodeBind.js +++ b/src/NodeBind.js @@ -17,6 +17,14 @@ var filter = Array.prototype.filter.call.bind(Array.prototype.filter); + function getTreeScope(node) { + while (node.parentNode) { + node = node.parentNode; + } + + return typeof node.getElementById === 'function' ? node : null; + } + // JScript does not have __proto__. We wrap all object literals with // createObject which uses Object.create, Object.defineProperty and // Object.getOwnPropertyDescriptor to create a new object that does the exact @@ -247,8 +255,6 @@ // http://www.whatwg.org/specs/web-apps/current-work/multipage/number-state.html#radio-button-group // function getAssociatedRadioButtons(element) { - if (!element.ownerDocument.contains(element)) - return []; if (element.form) { return filter(element.form.elements, function(el) { return el != element && @@ -257,7 +263,10 @@ el.name == element.name; }); } else { - var radios = element.ownerDocument.querySelectorAll( + var treeScope = getTreeScope(element); + if (!treeScope) + return []; + var radios = treeScope.querySelectorAll( 'input[type="radio"][name="' + element.name + '"]'); return filter(radios, function(el) { return el != element && !el.form; diff --git a/tests/tests.js b/tests/tests.js index d0a5088..bd864c6 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -439,11 +439,11 @@ suite('Form Element Bindings', function() { assert.isFalse(input.checked); }); - test('(Radio)Input.checked 2', function() { + function radioInputChecked2(host) { var model = {val1: true, val2: false, val3: false, val4: true}; var RADIO_GROUP_NAME = 'test'; - var container = testDiv.appendChild(document.createElement('div')); + var container = host.appendChild(document.createElement('div')); var el1 = container.appendChild(document.createElement('input')); el1.type = 'radio'; @@ -492,9 +492,20 @@ suite('Form Element Bindings', function() { assert.strictEqual(false, model.val2); assert.strictEqual(true, model.val3); assert.strictEqual(true, model.val4); + } + + test('(Radio)Input.checked 2', function() { + radioInputChecked2(testDiv); }); - test('(Radio)Input.checked - multiple forms', function() { + test('(Radio)Input.checked 2 - ShadowRoot', function() { + var div = document.createElement('div'); + var shadowRoot = div.webkitCreateShadowRoot(); + radioInputChecked2(shadowRoot); + unbindAll(shadowRoot); + }); + + function radioInputCheckedMultipleForms(host) { var model = {val1: true, val2: false, val3: false, val4: true}; var RADIO_GROUP_NAME = 'test'; @@ -545,6 +556,17 @@ suite('Form Element Bindings', function() { // Radio buttons in form1 should be unaffected assert.strictEqual(false, model.val1); assert.strictEqual(true, model.val2); + } + + test('(Radio)Input.checked - multiple forms', function() { + radioInputCheckedMultipleForms(testDiv); + }); + +test('(Radio)Input.checked - multiple forms - ShadowRoot', function() { + var div = document.createElement('div'); + var shadowRoot = div.webkitCreateShadowRoot(); + radioInputCheckedMultipleForms(shadowRoot); + unbindAll(shadowRoot); }); test('Select.selectedIndex', function() {