From b6f3f362e7d2c57fab4588f58fe26a35e072e805 Mon Sep 17 00:00:00 2001 From: John Messerly Date: Tue, 14 Apr 2015 11:28:58 -0700 Subject: [PATCH] fixes #285, getElementById on DocumentFragment --- src/ShadowDOM/wrappers/Document.js | 3 +- src/ShadowDOM/wrappers/ShadowRoot.js | 8 -- src/ShadowDOM/wrappers/generic.js | 2 + src/ShadowDOM/wrappers/node-interfaces.js | 9 ++ .../js/NonElementParentNodeInterface.js | 108 ++++++++++++++++++ tests/ShadowDOM/js/ShadowRoot.js | 31 ----- tests/ShadowDOM/tests.js | 1 + 7 files changed, 122 insertions(+), 40 deletions(-) create mode 100644 tests/ShadowDOM/js/NonElementParentNodeInterface.js diff --git a/src/ShadowDOM/wrappers/Document.js b/src/ShadowDOM/wrappers/Document.js index e704375..6bc018a 100644 --- a/src/ShadowDOM/wrappers/Document.js +++ b/src/ShadowDOM/wrappers/Document.js @@ -14,6 +14,7 @@ var GetElementsByInterface = scope.GetElementsByInterface; var Node = scope.wrappers.Node; var ParentNodeInterface = scope.ParentNodeInterface; + var NonElementParentNodeInterface = scope.NonElementParentNodeInterface; var Selection = scope.wrappers.Selection; var SelectorsInterface = scope.SelectorsInterface; var ShadowRoot = scope.wrappers.ShadowRoot; @@ -68,7 +69,6 @@ 'createEventNS', 'createRange', 'createTextNode', - 'getElementById' ].forEach(wrapMethod); var originalAdoptNode = document.adoptNode; @@ -302,6 +302,7 @@ mixin(Document.prototype, GetElementsByInterface); mixin(Document.prototype, ParentNodeInterface); mixin(Document.prototype, SelectorsInterface); + mixin(Document.prototype, NonElementParentNodeInterface); mixin(Document.prototype, { get implementation() { diff --git a/src/ShadowDOM/wrappers/ShadowRoot.js b/src/ShadowDOM/wrappers/ShadowRoot.js index 011ad33..9a08655 100644 --- a/src/ShadowDOM/wrappers/ShadowRoot.js +++ b/src/ShadowDOM/wrappers/ShadowRoot.js @@ -25,8 +25,6 @@ var shadowHostTable = new WeakMap(); var nextOlderShadowTreeTable = new WeakMap(); - var spaceCharRe = /[ \t\n\r\f]/; - function ShadowRoot(hostWrapper) { var node = unwrap(unsafeUnwrap(hostWrapper).ownerDocument.createDocumentFragment()); DocumentFragment.call(this, node); @@ -70,12 +68,6 @@ elementFromPoint: function(x, y) { return elementFromPoint(this, this.ownerDocument, x, y); }, - - getElementById: function(id) { - if (spaceCharRe.test(id)) - return null; - return this.querySelector('[id="' + id + '"]'); - } }); scope.wrappers.ShadowRoot = ShadowRoot; diff --git a/src/ShadowDOM/wrappers/generic.js b/src/ShadowDOM/wrappers/generic.js index 6e5819f..c18e3ff 100644 --- a/src/ShadowDOM/wrappers/generic.js +++ b/src/ShadowDOM/wrappers/generic.js @@ -12,6 +12,7 @@ 'use strict'; var GetElementsByInterface = scope.GetElementsByInterface; + var NonElementParentNodeInterface = scope.NonElementParentNodeInterface; var ParentNodeInterface = scope.ParentNodeInterface; var SelectorsInterface = scope.SelectorsInterface; var mixin = scope.mixin; @@ -21,6 +22,7 @@ mixin(DocumentFragment.prototype, ParentNodeInterface); mixin(DocumentFragment.prototype, SelectorsInterface); mixin(DocumentFragment.prototype, GetElementsByInterface); + mixin(DocumentFragment.prototype, NonElementParentNodeInterface); var Comment = registerObject(document.createComment('')); diff --git a/src/ShadowDOM/wrappers/node-interfaces.js b/src/ShadowDOM/wrappers/node-interfaces.js index 91843b4..622f425 100644 --- a/src/ShadowDOM/wrappers/node-interfaces.js +++ b/src/ShadowDOM/wrappers/node-interfaces.js @@ -75,7 +75,16 @@ } }; + var NonElementParentNodeInterface = { + getElementById: function(id) { + if (/[ \t\n\r\f]/.test(id)) + return null; + return this.querySelector('[id="' + id + '"]'); + } + }; + scope.ChildNodeInterface = ChildNodeInterface; + scope.NonElementParentNodeInterface = NonElementParentNodeInterface; scope.ParentNodeInterface = ParentNodeInterface; })(window.ShadowDOMPolyfill); diff --git a/tests/ShadowDOM/js/NonElementParentNodeInterface.js b/tests/ShadowDOM/js/NonElementParentNodeInterface.js new file mode 100644 index 0000000..4fac0d6 --- /dev/null +++ b/tests/ShadowDOM/js/NonElementParentNodeInterface.js @@ -0,0 +1,108 @@ +/** + * @license + * Copyright (c) 2015 The Polymer Project Authors. All rights reserved. + * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt + * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt + * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt + * Code distributed by Google as part of the polymer project is also + * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt + */ + +suite('NonElementParentNodeInterface', function() { + + var wrap = ShadowDOMPolyfill.wrap; + + var div; + setup(function() { + div = document.createElement('div'); + document.body.appendChild(div); + }); + + teardown(function() { + if (div && div.parentNode) + div.parentNode.removeChild(div); + }); + + test('getElementById', function() { + div.innerHTML = ''; + var a = div.firstChild; + var b = div.lastChild; + + assert.equal(document.getElementById('a'), a); + assert.equal(document.getElementById('b'), b); + }); + + test('getElementById in shadowRoot', function() { + var sr = div.createShadowRoot(); + sr.innerHTML = ''; + var a = sr.firstChild; + var b = sr.lastChild; + + assert.equal(sr.getElementById('a'), a); + assert.equal(sr.getElementById('b'), b); + assert.isNull(document.getElementById('a')); + assert.isNull(wrap(document).getElementById('b')); + + div.offsetHeight; + + // Check after rendering: + assert.equal(sr.getElementById('a'), a); + assert.equal(sr.getElementById('b'), b); + assert.isNull(document.getElementById('a')); + assert.isNull(wrap(document).getElementById('b')); + }); + + test('getElementById with a non CSS ID', function() { + var sr = div.createShadowRoot(); + sr.innerHTML = ''; + var a = sr.firstChild; + var b = sr.lastChild; + + assert.equal(sr.getElementById(1), a); + assert.equal(sr.getElementById(2), b); + assert.isNull(document.getElementById(1)); + assert.isNull(wrap(document).getElementById(2)); + + div.offsetHeight; + + // Check after rendering: + assert.equal(sr.getElementById(1), a); + assert.equal(sr.getElementById(2), b); + assert.isNull(document.getElementById(1)); + assert.isNull(wrap(document).getElementById(2)); + }); + + test('getElementById with a non ID', function() { + var sr = div.createShadowRoot(); + sr.innerHTML = ''; + var a = sr.firstChild; + + assert.isNull(sr.getElementById('a b')); + }); + + + test('getElementById in DocumentFragment', function() { + var df = document.createDocumentFragment(); + df.innerHTML = ''; + var a = df.firstChild; + var b = df.lastChild; + + assert.equal(df.getElementById('a'), a); + assert.equal(df.getElementById('b'), b); + }); + + test('getElementById in template content', function() { + div.innerHTML = ''; + var template = div.firstChild; + var content = template.content; + + var a = content.firstChild; + var b = content.lastChild; + + assert.equal(content.getElementById('a'), a); + assert.equal(content.getElementById('b'), b); + assert.isNull(document.getElementById('a')); + assert.isNull(wrap(document).getElementById('b')); + }); + +}); diff --git a/tests/ShadowDOM/js/ShadowRoot.js b/tests/ShadowDOM/js/ShadowRoot.js index 62478fd..6829d57 100644 --- a/tests/ShadowDOM/js/ShadowRoot.js +++ b/tests/ShadowDOM/js/ShadowRoot.js @@ -36,37 +36,6 @@ suite('ShadowRoot', function() { assert.equal(sr2.elementFromPoint(5, 5), null); }); - test('getElementById', function() { - var div = document.createElement('div'); - var sr = div.createShadowRoot(); - sr.innerHTML = ''; - var a = sr.firstChild; - var b = sr.lastChild; - - assert.equal(sr.getElementById('a'), a); - assert.equal(sr.getElementById('b'), b); - }); - - test('getElementById with a non CSS ID', function() { - var div = document.createElement('div'); - var sr = div.createShadowRoot(); - sr.innerHTML = ''; - var a = sr.firstChild; - var b = sr.lastChild; - - assert.equal(sr.getElementById(1), a); - assert.equal(sr.getElementById(2), b); - }); - - test('getElementById with a non ID', function() { - var div = document.createElement('div'); - var sr = div.createShadowRoot(); - sr.innerHTML = ''; - var a = sr.firstChild; - - assert.isNull(sr.getElementById('a b')); - }); - test('olderShadowRoot', function() { var host = document.createElement('div'); host.innerHTML = 'ab'; diff --git a/tests/ShadowDOM/tests.js b/tests/ShadowDOM/tests.js index 2b2cb76..85777b5 100644 --- a/tests/ShadowDOM/tests.js +++ b/tests/ShadowDOM/tests.js @@ -118,6 +118,7 @@ var modules = [ 'MutationObserver/shadow-root.js', 'MutationObserver/transient.js', 'Node.js', + 'NonElementParentNodeInterface.js', 'ParentNodeInterface.js', 'Range.js', 'SVGElement.js',