diff --git a/src/api/attributes.spec.ts b/src/api/attributes.spec.ts index 5b97d8ab63..959ad3a6e2 100644 --- a/src/api/attributes.spec.ts +++ b/src/api/attributes.spec.ts @@ -797,6 +797,22 @@ describe('$(...)', () => { expect($text('body').html()).toBe(mixedText); }); + + it('(KEY) : should be case-insensitive in HTML mode', () => { + const $html = load('
'); + $html('div').removeAttr('CLASS'); + expect($html('div').attr('class')).toBeUndefined(); + }); + + it('(KEY) : should remain case-sensitive in XML mode', () => { + const $xml = load('', { xmlMode: true }); + // A differently-cased name must not remove the attribute in XML mode. + $xml('Foo').removeAttr('BAR'); + expect($xml('Foo').attr('Bar')).toBe('x'); + // The exact name still removes it. + $xml('Foo').removeAttr('Bar'); + expect($xml('Foo').attr('Bar')).toBeUndefined(); + }); }); describe('.hasClass', () => { diff --git a/src/api/attributes.ts b/src/api/attributes.ts index dbd46dad9e..5529527c8d 100644 --- a/src/api/attributes.ts +++ b/src/api/attributes.ts @@ -880,8 +880,10 @@ export function removeAttr( const attrNames = splitNames(name); for (const attrName of attrNames) { + // HTML attribute names are case-insensitive; XML mode preserves case. + const lookup = this.options.xmlMode ? attrName : attrName.toLowerCase(); domEach(this, (elem) => { - if (isTag(elem)) removeAttribute(elem, attrName); + if (isTag(elem)) removeAttribute(elem, lookup); }); }