8000 Attributes: Make `.attr( name, false )` remove for all non-ARIA attrs by mgol · Pull Request #5452 · jquery/jquery · GitHub
[go: up one dir, main page]

Skip to content

Attributes: Make .attr( name, false ) remove for all non-ARIA attrs #5452

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

Merged
merged 1 commit into from
Mar 19, 2024

Conversation

mgol
Copy link
Member
@mgol mgol commented Mar 18, 2024

Summary

The HTML spec defines boolean attributes:
https://html.spec.whatwg.org/#boolean-attributes
that often correlate with boolean properties. If the attribute is missing, it correlates with the false property value, if it's present - the true property value. The only valid values are an empty string or the attribute name.

jQuery tried to be helpful here and treated boolean attributes in a special way in the .attr() API:

  1. For the getter, as long as the attribute was present, it was returning the attribute name lowercased, ignoring the value.
  2. For the setter, it was removing the attribute when false was passed; otherwise, it was ignoring the passed value and set the attribute - interestingly, in jQuery >=3 not lowercased anymore.

The problem is the spec occasionally converts boolean attributes into ones with additional attribute values with special behavior - one such example is the new "until-found" value for the hidden attribute. Our setter normalization means passing those values is impossible with jQuery. Also, new boolean attributes are introduced occasionally and jQuery cannot easily add them to the list without incurring breaking changes.

This patch removes any special handling of boolean attributes - the getter returns the value as-is and the setter sets the provided value.

To provide better backwards compatibility with the very frequent false value provided to remove the attribute, this patch makes false trigger attribute removal for ALL non-ARIA attributes. ARIA attributes are exempt from the rule since many of them recognize "false" as a valid value with semantics different than the attribute missing. To remove an ARIA attribute, use .removeAttr() or pass null as the value to .attr() which doesn't have this exception.

Fixes gh-5388

Richard Gibson is added as a co-author.

Checklist

The HTML spec defines boolean attributes:
https://html.spec.whatwg.org/#boolean-attributes
that often correlate with boolean properties. If the attribute is missing, it
correlates with the `false` property value, if it's present - the `true`
property value. The only valid values are an empty string or the attribute name.

jQuery tried to be helpful here and treated boolean attributes in a special way
in the `.attr()` API:
1. For the getter, as long as the attribute was present, it was returning the
   attribute name lowercased, ignoring the value.
2. For the setter, it was removing the attribute when `false` was passed;
   otherwise, it was ignoring the passed value and set the attribute -
   interestingly, in jQuery `>=3` not lowercased anymore.

The problem is the spec occasionally converts boolean attributes into ones with
additional attribute values with special behavior - one such example is the new
`"until-found"` value for the `hidden` attribute. Our setter normalization
means passing those values is impossible with jQuery. Also, new boolean
attributes are introduced occasionally and jQuery cannot easily add them to the
list without incurring breaking changes.

This patch removes any special handling of boolean attributes - the getter
returns the value as-is and the setter sets the provided value.

To provide better backwards compatibility with the very frequent `false` value
provided to remove the attribute, this patch makes `false` trigger attribute
removal for ALL non-ARIA attributes. ARIA attributes are exempt from the rule
since many of them recognize `"false"` as a valid value with semantics different
than the attribute missing. To remove an ARIA attribute, use `.removeAttr()` or
pass `null` as the value to `.attr()` which doesn't have this exception.

Fixes jquerygh-5388

Co-authored-by: Richard Gibson <richard.gibson@gmail.com>
@mgol mgol added this to the 4.0.0 milestone Mar 18, 2024
@mgol mgol requested a review from gibson042 March 18, 2024 22:13
@mgol mgol self-assigned this Mar 18, 2024
@mgol
Copy link
Member Author
mgol commented Mar 18, 2024

Size differences:

main @f80e78ef3e7ded1fc693465d02dfb07510ded0ab
   raw     gz Filename
  -273   -109 dist/jquery.min.js
  -273   -102 dist/jquery.slim.min.js
  -273   -104 dist-module/jquery.module.min.js
  -273   -100 dist-module/jquery.slim.module.min.js

Copy link
Member
@gibson042 gibson042 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Copy link
Member
@timmywil timmywil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incredible how little the tests needed to change!

@mgol mgol merged commit 063831b into jquery:main Mar 19, 2024
@mgol mgol deleted the attr-false-removal branch March 19, 2024 23:46
mgol added a commit to mgol/jquery-ui that referenced this pull request Mar 25, 2024
jQuery PR jquery/jquery#5452 removed special handling of boolean attributes.
Thankfully, this only broke a single jQuery UI test.
mgol added a commit to jquery/jquery-ui that referenced this pull request Mar 26, 2024
jQuery PR jquery/jquery#5452 removed special handling of boolean attributes.
Thankfully, this only broke a single jQuery UI test.

Closes gh-2220
mgol added a commit to mgol/jquery-migrate that referenced this pull request Oct 8, 2024
Restore & warn against:
* boolean attributes set to something different than their lowercase names
* boolean attributes queried when set to something different than their
  lowercase names
* non-boolean non-ARIA attributes set to `false`

Fixes jquerygh-504
Ref jquery/jquery#5452
Ref jquery/api.jquery.com#1243
mgol added a commit to mgol/api.jquery.com that referenced this pull request Oct 9, 2024
mgol added a commit to mgol/api.jquery.com that referenced this pull request Oct 9, 2024
mgol added a commit to mgol/api.jquery.com that referenced this pull request Oct 9, 2024
mgol added a commit to mgol/api.jquery.com that referenced this pull request Oct 14, 2024
mgol added a commit to mgol/jquery-migrate that referenced this pull request Oct 15, 2024
Restore & warn against:
* boolean attributes set to something different than their lowercase names
* boolean attributes queried when set to something different than their
  lowercase names
* non-boolean non-ARIA attributes set to `false`

Fixes jquerygh-504
Ref jquery/jquery#5452
Ref jquery/api.jquery.com#1243
mgol added a commit to mgol/jquery-migrate that referenced this pull request Oct 28, 2024
Restore & warn against:
* boolean attributes set to something different than their lowercase names
* boolean attributes queried when set to something different than their
  lowercase names
* non-boolean non-ARIA attributes set to `false`

Fixes jquerygh-504
Ref jquery/jquery#5452
Ref jquery/api.jquery.com#1243
mgol added a commit to mgol/jquery-migrate that referenced this pull request Oct 29, 2024
Restore & warn against:
* boolean attributes set to something different than their lowercase names
* boolean attributes queried when set to something different than their
  lowercase names
* non-boolean non-ARIA attributes set to `false`

Fixes jquerygh-504
Ref jquery/jquery#5452
Ref jquery/api.jquery.com#1243
mgol added a commit to jquery/jquery-migrate that referenced this pull request Nov 19, 2024
….x (#540)

Restore & warn against:
* boolean attributes set to something different than their lowercase names
* boolean attributes queried when set to something different than their
  lowercase names
* non-boolean non-ARIA attributes set to `false`

Fixes gh-504
Closes gh-540
Ref jquery/jquery#5452
Ref jquery/api.jquery.com#1243
mgol added a commit to mgol/api.jquery.com that referenced this pull request Dec 16, 2024
mgol added a commit to jquery/api.jquery.com that referenced this pull request Dec 16, 2024
mgol added a commit to mgol/jquery that referenced this pull request Jan 5, 2025
The `hidden` attribute used to be a boolean one but it gained a new
`until-found` eventually. This led us to change the way we handle boolean
attributes in jQuery 4.0 in jquerygh-5452 to avoid these issues in the future.

That said, currently from the attributes we treat as boolean only `hidden`
has gained an extra value, let's support it.

Ref jquerygh-5388
Ref jquerygh-5452
mgol added a commit to mgol/jquery that referenced this pull request Jan 5, 2025
The `hidden` attribute used to be a boolean one but it gained a new
`until-found` eventually. This led us to change the way we handle boolean
attributes in jQuery 4.0 in jquerygh-5452 to avoid these issues in the future.

That said, currently from the attributes we treat as boolean only `hidden`
has gained an extra value, let's support it.

Ref jquerygh-5388
Ref jquerygh-5452
mgol added a commit to mgol/jquery that referenced this pull request Jan 5, 2025
The `hidden` attribute used to be a boolean one but it gained a new
`until-found` eventually. This led us to change the way we handle boolean
attributes in jQuery 4.0 in jquerygh-5452 to avoid these issues in the future.

That said, currently from the attributes we treat as boolean only `hidden`
has gained an extra value, let's support it.

Ref jquerygh-5388
Ref jquerygh-5452
mgol added a commit to mgol/jquery that referenced this pull request Jan 14, 2025
The `hidden` attribute used to be a boolean one but it gained a new
`until-found` eventually. This led us to change the way we handle boolean
attributes in jQuery 4.0 in jquerygh-5452 to avoid these issues in the future.

That said, currently from the attributes we treat as boolean only `hidden`
has gained an extra value, let's support it.

Ref jquerygh-5388
Ref jquerygh-5452
mgol added a commit to mgol/jquery that referenced this pull request Jan 16, 2025
The `hidden` attribute used to be a boolean one but it gained a new
`until-found` eventually. This led us to change the way we handle boolean
attributes in jQuery 4.0 in jquerygh-5452 to avoid these issues in the future.

That said, currently from the attributes we treat as boolean only `hidden`
has gained an extra value, let's support it.

Ref jquerygh-5388
Ref jquerygh-5452
mgol added a commit that referenced this pull request Jan 16, 2025
The `hidden` attribute used to be a boolean one but it gained a new
`until-found` eventually. This led us to change the way we handle boolean
attributes in jQuery 4.0 in gh-5452 to avoid these issues in the future.

That said, currently from the attributes we treat as boolean only `hidden`
has gained an extra value, let's support it.

Closes gh-5607
Ref gh-5388
Ref gh-5452
mgol added a commit to mgol/jquery that referenced this pull request Jan 27, 2025
The `hidden` attribute used to be a boolean one but it gained a new
`until-found` eventually. This led us to change the way we handle boolean
attributes in jQuery 4.0 in jquerygh-5452 to avoid these issues in the future.

We haven't added an explicit test for the `"until-found"` value of the
`hidden` attribute which triggered this decision so far, though.
Backport the test from jquerygh-5607 which landed on `3.x-stable` so that we
do test it.

Ref jquerygh-5452
Ref jquerygh-5607

(cherry picked from commit 85290c5)
mgol added a commit to mgol/jquery that referenced this pull request Jan 27, 2025
The `hidden` attribute used to be a boolean one but it gained a new
`until-found` eventually. This led us to change the way we handle boolean
attributes in jQuery 4.0 in jquerygh-5452 to avoid these issues in the future.

We haven't added an explicit test for the `"until-found"` value of the
`hidden` attribute which triggered this decision so far, though.
Backport the test from jquerygh-5607 which landed on `3.x-stable` so that we
do test it.

Ref jquerygh-5452
Ref jquerygh-5607

(cherry picked from commit 85290c5)
mgol added a commit that referenced this pull request Feb 24, 2025
The `hidden` attribute used to be a boolean one but it gained a new
`until-found` eventually. This led us to change the way we handle boolean
attributes in jQuery 4.0 in gh-5452 to avoid these issues in the future.

We haven't added an explicit test for the `"until-found"` value of the
`hidden` attribute which triggered this decision so far, though.
Backport the test from gh-5607 which landed on `3.x-stable` so that we
do test it.

Closes gh-5619
Ref gh-5452
Ref gh-5607

(cherry picked from commit 85290c5)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

Update the rules for boolean attributes for 4.0
3 participants
0