-
Notifications
You must be signed in to change notification settings - Fork 266
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
attr: Document attr(key, null) to remove attribute #523
Comments
Hi @Krinkle. Maybe there's something I haven't checked but it seems to me that jQuery returns Two examples (taken from the // don't get/set attributes on text, comment and attribute nodes
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
return;
} and // Non-existent attributes return null, we normalize to undefined
return ret == null ?
undefined :
ret; |
@Krinkle: is there a benefit to using |
@AurelioDeRosa I know we return undefined now, but I think it used to return null in an older version. And of course the native getAttribute always returns null. @kswedberg The main benefit is that it allows roundtripping of values. I'd recommend we do this with both undefined and null (right now null removes the attribute, and passing undefined is a weird no-op that neither sets a casted string "undefined" nor removes the attribute). // Restore foo
var val = foo.attr(key);
foo.attr(key, 'changed');
foo.attr(key, val);
// Sync bar with foo
var val = foo.attr(key);
bar.attr(key, val); I've run into this a various times in the past few years when a widget overrides an attribute and temporarily and stores the result of calling |
Setting |
I'm aware of 5571. This shouldn't affect the original issue though. I thought we fixed that problem by using However it seems that this is no longer the case (or never was?). Instead passing undefined makes it fall through the cracks. From reading the source code this doesn't seem intended/explicit. Though the test cases do cover it explicitly. equal( typeof jQuery("#name").attr( "maxlength", undefined ), "object", ".attr('attribute', undefined) is chainable (#5571)" );
equal( jQuery("#name").attr( "maxlength", undefined ).attr("maxlength"), "5", ".attr('attribute', undefined) does not change value (#5571)" );
equal( jQuery("#name").attr( "nonexisting", undefined ).attr("nonexisting"), undefined, ".attr('attribute', undefined) does not create attribute (#5571)" ); It currently uses Passing any value as second argument (say, undefined) should imho either result in either a getter (like old jQuery, not chainable, not desirable), or result in setting value "undefined" (cast to string), or some other setter-like behaviour (e.g. removing the attribute, like we do with null). Right now it triggers setter-like behaviour (chainable return), but the value is silently rejected and nothing is either get, set or removed. Attributes can only contain string values (no other primitives like numbers or booleans and no non-primitive values). If we're rejecting it on being an invalid value, should we reject other invalid values? The native setAttribute, for example, does behave this way (any value passed is set as a string).
While inconsistent with the DOM, at least we are being consistent internally. All effected access-based methods ( $('<input>').val(undefined).val() === "" I see now that it was intentionally implemented as a no-op, your idea in fact (@gibson042):
Perhaps it's a weird quirk not worth changing that we just need to document? |
I like the idea of round-tripping as well, but our previous decisions here seem to have us boxed in if we want to maintain strict compat. Having not yet checked the impact of such a decision, I would be okay with having a breaking change so that |
There are at least two options for (slightly) breaking backcompat in favor of
|
The discussion around the behavior of |
@jugglinmike Yep. My main request here is to document (and thereby acknowledge) that Right now, passing However, this isn't very valuable unless we change |
In addition, introduce the `null` value type to more completely describe the `attr` method's signature. jQuery implements explicit support for this behavior [1]: if ( value === null ) { jQuery.removeAttr( elem, name ); return; } and also maintains unit tests to verify it [2]: jQuery( "#name" ).attr( "name", null ); assert.equal( jQuery( "#name" ).attr( "name" ), undefined, "Remove name attribute" ); Fixes jquerygh-523 [1] https://github.com/jquery/jquery/blob/1823a715660a5f31dd7e05672e9ad020066256a9/src/attributes/attr.js#L55-L58 [2] https://github.com/jquery/jquery/blob/1823a715660a5f31dd7e05672e9ad020066256a9/test/unit/attributes.js#L283-L284
In addition, introduce the `null` value type to more completely describe the `attr` method's signature. jQuery implements explicit support for this behavior [1]: if ( value === null ) { jQuery.removeAttr( elem, name ); return; } and also maintains unit tests to verify it [2]: jQuery( "#name" ).attr( "name", null ); assert.equal( jQuery( "#name" ).attr( "name" ), undefined, "Remove name attribute" ); Fixes jquerygh-523 [1] https://github.com/jquery/jquery/blob/1823a715660a5f31dd7e05672e9ad020066256a9/src/attributes/attr.js#L55-L58 [2] https://github.com/jquery/jquery/blob/1823a715660a5f31dd7e05672e9ad020066256a9/test/unit/attributes.js#L283-L284
I still don't see this reflected on https://api.jquery.com/attr/ ? |
Our unit tests cover it explicitly, and the code implements it explicitly:
From the API perspective I'd also say this makes a lot of sense as it allows roundtripping between the getter returning null and the setter receiving null.
The text was updated successfully, but these errors were encountered: