diff --git a/src/CustomElements.js b/src/CustomElements.js index d9f4c7c..6e132cb 100644 --- a/src/CustomElements.js +++ b/src/CustomElements.js @@ -101,7 +101,7 @@ if (useNative) { throw new Error('document.register: first argument (\'name\') must contain a dash (\'-\'). Argument provided was \'' + String(name) + '\'.'); } // record name - definition.name = name; + definition.name = name.toLowerCase(); // must have a prototype, default to an extension of HTMLElement // TODO(sjmiles): probably should throw if no prototype, check spec if (!definition.prototype) { @@ -110,7 +110,7 @@ if (useNative) { throw new Error('Options missing required prototype property'); } // elements may only be registered once - if (registry[name]) { + if (getRegisteredDefinition(name)) { throw new Error('DuplicateDefinitionError: a type with name \'' + String(name) + '\' is already registered'); } // ensure a lifecycle object so we don't have to null test it @@ -144,7 +144,7 @@ if (useNative) { } function ancestry(extnds) { - var extendee = registry[extnds]; + var extendee = getRegisteredDefinition(extnds); if (extendee) { return ancestry(extendee.extends).concat([extendee]); } @@ -307,8 +307,14 @@ if (useNative) { var registry = {}; + function getRegisteredDefinition(name) { + if (name) { + return registry[name.toLowerCase()]; + } + } + function registerDefinition(name, definition) { - registry[name] = definition; + registry[name.toLowerCase()] = definition; } function generateConstructor(definition) { @@ -320,7 +326,7 @@ if (useNative) { function createElement(tag, typeExtension) { // TODO(sjmiles): ignore 'tag' when using 'typeExtension', we could // error check it, or perhaps there should only ever be one argument - var definition = registry[typeExtension || tag]; + var definition = getRegisteredDefinition(typeExtension || tag); if (definition) { return new definition.ctor(); } @@ -330,7 +336,7 @@ if (useNative) { function upgradeElement(element) { if (!element.__upgraded__ && (element.nodeType === Node.ELEMENT_NODE)) { var type = element.getAttribute('is') || element.localName; - var definition = registry[type]; + var definition = getRegisteredDefinition(type); return definition && upgrade(element, definition); } } diff --git a/test/js/customElements.js b/test/js/customElements.js index d3cc3cf..48201ed 100644 --- a/test/js/customElements.js +++ b/test/js/customElements.js @@ -36,14 +36,14 @@ }); test('document.register requires name argument to be unique', function() { - var proto = {prototype: Object.create(HTMLElement.prototype)}; - document.register('x-duplicate', proto); - try { + var proto = {prototype: Object.create(HTMLElement.prototype)}; document.register('x-duplicate', proto); - } catch(x) { - return; - } - assert.ok(false, 'document.register failed to throw when called multiple times with the same element name'); + try { + document.register('x-duplicate', proto); + } catch(x) { + return; + } + assert.ok(false, 'document.register failed to throw when called multiple times with the same element name'); }); test('document.register create via new', function() { @@ -74,6 +74,23 @@ assert.equal(xfoo.textContent, '[x-foo2]'); }); + test('document.register treats names as case insensitive', function() { + var proto = {prototype: Object.create(HTMLElement.prototype)}; + proto.prototype.isXCase = true; + var XCase = document.register('X-CASE', proto); + // createElement + var x = document.createElement('X-CASE'); + assert.equal(x.isXCase, true); + x = document.createElement('x-case'); + assert.equal(x.isXCase, true); + // upgrade + work.innerHTML = ''; + CustomElements.takeRecords(); + assert.equal(work.firstChild.isXCase, true); + assert.equal(work.firstChild.nextSibling.isXCase, true); + }); + + test('document.register create multiple instances', function() { var XFooPrototype = Object.create(HTMLElement.prototype); XFooPrototype.bluate = function() {