From 53a9cdfeb1c65b6663b806cf062fddebd5e9d670 Mon Sep 17 00:00:00 2001 From: Trey Shugart Date: Fri, 17 Jun 2016 17:04:25 +1000 Subject: [PATCH] #554 - upgrade step for existing attributes (#558) Fixes #554. Add upgrade step for calling attributeChangedCallback for all existing attributes. --- src/CustomElements/v1/CustomElements.js | 14 ++++++-- tests/CustomElements/v1/js/customElements.js | 37 ++++++++++++++++++-- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/CustomElements/v1/CustomElements.js b/src/CustomElements/v1/CustomElements.js index f7fc2dc2e..34f65084a 100644 --- a/src/CustomElements/v1/CustomElements.js +++ b/src/CustomElements/v1/CustomElements.js @@ -242,11 +242,21 @@ var CustomElementDefinition; new (definition.constructor)(); console.assert(this._newInstance == null); } - if (definition.attributeChangedCallback && definition.observedAttributes.length > 0) { + + var observedAttributes = definition.observedAttributes; + if (definition.attributeChangedCallback && observedAttributes.length > 0) { this._attributeObserver.observe(element, { attributes: true, attributeOldValue: true, - attributeFilter: definition.observedAttributes, + attributeFilter: observedAttributes, + }); + + // Trigger attributeChangedCallback for existing attributes. + // https://html.spec.whatwg.org/multipage/scripting.html#upgrades - part 1 + observedAttributes.forEach(function (name) { + if (element.hasAttribute(name)) { + element.attributeChangedCallback(name, null, element.getAttribute(name)); + } }); } } diff --git a/tests/CustomElements/v1/js/customElements.js b/tests/CustomElements/v1/js/customElements.js index 7fbd0205f..edcec453f 100644 --- a/tests/CustomElements/v1/js/customElements.js +++ b/tests/CustomElements/v1/js/customElements.js @@ -313,9 +313,42 @@ suite('customElements', function() { done(); }); + test('attributeChangedCallback for existing observed attributes', function (done) { + var changed = []; + class XBoo extends HTMLElement { + static get observedAttributes () { + return ['test1']; + } + attributeChangedCallback(name, oldValue, newValue) { + changed.push({ + name: name, + oldValue: oldValue, + newValue: newValue + }); + } + connectedCallback() { + this.innerHTML = 'testing'; + } + } + + var element = document.createElement('x-boo-at1'); + element.setAttribute('test1', 'test1'); + element.setAttribute('test2', 'test2'); + work.appendChild(element); + + customElements.define('x-boo-at1', XBoo); + customElements.flush(); + + assert.equal(changed.length, 1, 'should only trigger for observed attributes'); + assert.equal(changed[0].name, 'test1', 'name'); + assert.equal(changed[0].oldValue, null, 'oldValue'); + assert.equal(changed[0].newValue, 'test1', 'newValue'); + done(); + }); + test('customElements.get', function (done) { - class XBoo extensd HTMLElement {} - customElements.define('x-boo-get', XGetTest); + class XBoo extends HTMLElement {} + customElements.define('x-boo-get', XBoo); assert.equal(XBoo, customElements.get('x-boo-get')); done(); });