From 8ee223eb496e497042b5abf02162cec639c0b5b1 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Mon, 16 Dec 2013 13:03:10 -0800 Subject: [PATCH] Avoid conflicts with using Functions as Custom Element definitions Function.name is readonly, use defition.elementName to store tagname Add test Fixes #362 --- src/CustomElements.js | 8 ++++---- test/js/customElements.js | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/CustomElements.js b/src/CustomElements.js index dc8d15f..670d24a 100644 --- a/src/CustomElements.js +++ b/src/CustomElements.js @@ -112,7 +112,7 @@ if (useNative) { throw new Error('Options missing required prototype property'); } // record name - definition.name = name.toLowerCase(); + definition.elementName = name.toLowerCase(); // ensure a lifecycle object so we don't have to null test it definition.lifecycle = definition.lifecycle || {}; // build a list of ancestral custom elements (for native base detection) @@ -128,7 +128,7 @@ if (useNative) { // overrides to implement attributeChanged callback overrideAttributeApi(definition.prototype); // 7.1.5: Register the DEFINITION with DOCUMENT - registerDefinition(definition.name, definition); + registerDefinition(definition.elementName, definition); // 7.1.7. Run custom element constructor generation algorithm with PROTOTYPE // 7.1.8. Return the output of the previous step. definition.ctor = generateConstructor(definition); @@ -161,10 +161,10 @@ if (useNative) { baseTag = a.is && a.tag; } // our tag is our baseTag, if it exists, and otherwise just our name - definition.tag = baseTag || definition.name; + definition.tag = baseTag || definition.elementName; if (baseTag) { // if there is a base tag, use secondary 'is' specifier - definition.is = definition.name; + definition.is = definition.elementName; } } diff --git a/test/js/customElements.js b/test/js/customElements.js index bd00637..6b8a51f 100644 --- a/test/js/customElements.js +++ b/test/js/customElements.js @@ -243,6 +243,24 @@ xboo.setAttribute('foo', 'zot'); }); + test('document.register can use Functions as definitions', function() { + // function used as Custom Element defintion + function A$A() { + this.alive = true; + } + A$A.prototype = Object.create(HTMLElement.prototype); + // bind createdCallback to function body + A$A.prototype.createdCallback = A$A; + A$A = document.register('a-a', A$A); + // test via new + var a = new A$A(); + assert.equal(a.alive, true); + // test via parser upgrade + work.innerHTML = ''; + CustomElements.takeRecords(); + assert.equal(work.firstElementChild.alive, true); + }); + test('node.cloneNode upgrades', function(done) { var XBooPrototype = Object.create(HTMLElement.prototype); XBooPrototype.createdCallback = function() {