diff --git a/src/api/attributes.spec.ts b/src/api/attributes.spec.ts index 3e965b3dc2..52590323a8 100644 --- a/src/api/attributes.spec.ts +++ b/src/api/attributes.spec.ts @@ -179,6 +179,25 @@ describe('$(...)', () => { expect($pear).toBeInstanceOf($); }); + it('(key, value) : should remove attributes when called with undefined value', () => { + const $pear = $('.pear').attr('foo', 'bar'); + expect($pear.attr('foo')).toBe('bar'); + $pear.attr('foo', undefined); + expect($pear.attr('foo')).toBeUndefined(); + }); + + it('(map) : should remove attributes with undefined values', () => { + const $pear = $('.pear').attr({ + foo: 'bar', + style: 'color:red', + }); + expect($pear.attr('foo')).toBe('bar'); + expect($pear.attr('style')).toBe('color:red'); + $pear.attr({ foo: undefined, style: 'color:blue' }); + expect($pear.attr('foo')).toBeUndefined(); + expect($pear.attr('style')).toBe('color:blue'); + }); + it('(chaining) setting attr to undefined returns a $', () => { const $pear = $('.pear').attr('foo', undefined); expect($('.pear')).toHaveLength(1); diff --git a/src/api/attributes.ts b/src/api/attributes.ts index 24425c8b7d..698966e212 100644 --- a/src/api/attributes.ts +++ b/src/api/attributes.ts @@ -85,15 +85,15 @@ function getAttr( /** * Sets the value of an attribute. The attribute will be deleted if the value is - * `null`. + * `null` or `undefined`. * * @private * @param el - The element to set the attribute on. * @param name - The attribute's name. * @param value - The attribute's value. */ -function setAttr(el: Element, name: string, value: string | null) { - if (value === null) { +function setAttr(el: Element, name: string, value: string | null | undefined) { + if (value === null || value === undefined) { removeAttribute(el, name); } else { el.attribs[name] = `${value}`; @@ -140,8 +140,8 @@ export function attr( ): Record | undefined; /** * Method for setting attributes. Sets the attribute value for all elements in - * the matched set. If you set an attribute's value to `null`, you remove that - * attribute. You may also pass a `map` and `function`. + * the matched set. If you set an attribute's value to `null` or `undefined`, + * you remove that attribute. You may also pass a `map` and `function`. * * @category Attributes * @example @@ -162,7 +162,8 @@ export function attr( value?: | string | null - | ((this: Element, i: number, attrib: string) => string | null), + | undefined + | ((this: Element, i: number, attrib: string) => string | null | undefined), ): Cheerio; /** * Method for setting multiple attributes at once. Sets the attribute value for @@ -183,18 +184,19 @@ export function attr( */ export function attr( this: Cheerio, - values: Record, + values: Record, ): Cheerio; export function attr( this: Cheerio, - name?: string | Record, + name?: string | Record, value?: | string | null - | ((this: Element, i: number, attrib: string) => string | null), + | undefined + | ((this: Element, i: number, attrib: string) => string | null | undefined), ): string | Cheerio | undefined | Record { // Set the value (with attr map support) - if (typeof name === 'object' || value !== undefined) { + if (typeof name === 'object' || arguments.length > 1) { if (typeof value === 'function') { if (typeof name !== 'string') { { @@ -726,7 +728,7 @@ export function data( } // Set the value (with attr map support) - if (typeof name === 'object' || value !== undefined) { + if (typeof name === 'object' || arguments.length > 1) { domEach(this, (el) => { if (isTag(el)) { if (typeof name === 'object') setData(el, name);