Skip to content

Commit 5dcfac0

Browse files
Merge pull request #51 from preactjs/ff-attribute-throw
Fix crash with empty attribute values
2 parents 9aff394 + 8b97be0 commit 5dcfac0

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed

src/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ function toCamelCase(str) {
9090

9191
function attributeChangedCallback(name, oldValue, newValue) {
9292
if (!this._vdom) return;
93+
// Attributes use `null` as an empty value whereas `undefined` is more
94+
// common in pure JS components, especially with default parameters.
95+
// When calling `node.removeAttribute()` we'll receive `null` as the new
96+
// value. See issue #50.
97+
newValue = newValue == null ? undefined : newValue;
9398
const props = {};
9499
props[name] = newValue;
95100
props[toCamelCase(name)] = newValue;

src/index.test.jsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,21 @@ describe('web components', () => {
4040
);
4141
});
4242

43+
function NullProps({ size = 'md' }) {
44+
return <div>{size.toUpperCase()}</div>;
45+
}
46+
47+
registerElement(NullProps, 'x-null-props', ['size'], { shadow: true });
48+
49+
// #50
50+
it('remove attributes without crashing', () => {
51+
const el = document.createElement('x-null-props');
52+
assert.doesNotThrow(() => (el.size = 'foo'));
53+
root.appendChild(el);
54+
55+
assert.doesNotThrow(() => el.removeAttribute('size'));
56+
});
57+
4358
describe('DOM properties', () => {
4459
it('passes property changes to props', () => {
4560
const el = document.createElement('x-clock');

0 commit comments

Comments
 (0)