Skip to content

Commit 1bff7c6

Browse files
committed
Check for inherited attrs in initializeAttrs
1 parent f3943cb commit 1bff7c6

2 files changed

Lines changed: 27 additions & 3 deletions

File tree

src/attr.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export function attr<K extends string>(proto: Record<K, attrValue>, key: K): voi
3535
* `@controller` decorator it should not call this manually.
3636
*/
3737
export function initializeAttrs(instance: HTMLElement, names?: Iterable<string>): void {
38-
if (!names) names = attrs.get(Object.getPrototypeOf(instance)) || []
38+
if (!names) names = new Set(getAttrNames(instance))
3939
for (const key of names) {
4040
const value = (<Record<PropertyKey, unknown>>(<unknown>instance))[key]
4141
const name = attrToAttributeName(key)
@@ -73,6 +73,12 @@ export function initializeAttrs(instance: HTMLElement, names?: Iterable<string>)
7373
}
7474
}
7575

76+
function getAttrNames(instance: HTMLElement | typeof HTMLElement): string[] {
77+
if (!instance || instance === HTMLElement) return []
78+
const proto = Object.getPrototypeOf(instance)
79+
return (attrs.get(proto) || []).concat(getAttrNames(proto))
80+
}
81+
7682
function attrToAttributeName(name: string): string {
7783
return `data-${name.replace(/([A-Z]($|[a-z]))/g, '-$1')}`.replace(/--/g, '-').toLowerCase()
7884
}

test/attr.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,15 @@ describe('initializeAttrs', () => {
155155

156156
describe('attr', () => {
157157
class AttrTestElement extends HTMLElement {}
158+
attr(AttrTestElement.prototype, 'foo')
159+
attr(AttrTestElement.prototype, 'bar')
158160
window.customElements.define('attr-test-element', AttrTestElement)
159161

162+
class ExtendedAttrTestElement extends AttrTestElement {}
163+
attr(ExtendedAttrTestElement.prototype, 'baz')
164+
window.customElements.define('extended-attr-test-element', ExtendedAttrTestElement)
165+
160166
it('populates the "default" list for initializeAttrs', () => {
161-
attr(AttrTestElement.prototype, 'foo')
162-
attr(AttrTestElement.prototype, 'bar')
163167
const instance = document.createElement('attr-test-element')
164168
instance.foo = 'hello'
165169
initializeAttrs(instance)
@@ -169,6 +173,20 @@ describe('attr', () => {
169173
expect(instance.getAttribute('data-foo')).to.equal('hello')
170174
expect(instance.getAttribute('data-bar')).to.equal('')
171175
})
176+
177+
it('includes attrs from extended elements', () => {
178+
const instance = document.createElement('extended-attr-test-element')
179+
instance.bar = 'hello'
180+
instance.baz = 'world'
181+
initializeAttrs(instance)
182+
expect(instance).to.have.property('foo', '')
183+
expect(instance).to.have.property('bar', 'hello')
184+
expect(instance).to.have.property('baz', 'world')
185+
expect(instance.getAttributeNames()).to.eql(['data-baz', 'data-foo', 'data-bar'])
186+
expect(instance.getAttribute('data-foo')).to.equal('')
187+
expect(instance.getAttribute('data-bar')).to.equal('hello')
188+
expect(instance.getAttribute('data-baz')).to.equal('world')
189+
})
172190
})
173191

174192
describe('defineObservedAttributes', () => {

0 commit comments

Comments
 (0)