Comments (8)
Oh, interesting. Perhaps we should update this list for 4.0 as this can be considered a breaking change.
Or we should get rid of this manual normalization, depending on users doing the right thing here. The biggest issue are possibly falsy checks on values since an empty string is also a valid value. This was also raised by @timmywil in a past issue where I proposed a similar simlification: #2946.
If we're worried about compat for such things, my guess would be we could limit this list to just a few entries like checked
& selected
. I feel keeping the list open-ended leads us to the same problems as the logic for auto-appending px
- the list is never complete and modifying this is both a maintenance burden as well as a potential source of application breakage. (the px
behavior was change to have a closed list in #4055)
Our list right now is:
checked
selected
async
autofocus
autoplay
controls
defer
disabled
hidden
ismap
loop
multiple
open
readonly
required
scoped
As Richard mentioned, hidden
is no longer even correct here but removing it from the list is a compat break so it'd be good to fit it into 4.0.
If we want to keep the logic for at least some attributes, I could see us doing so just for checked
& selected
; maybe disabled
. That said, I'd expect hidden
to also be a commonly used one and a good case where our behavior causes issues for future standards changes. If another name from the list gets similar treatment in standards, we won't be able to adjust without another breaking change. It might be more future-proof to give up on this normalization in 4.0 in the end.
Thoughts, @timmywil @gibson042?
from jquery.
Tentatively adding it to 4.0.0
blockers so that we don't release before discussing this first.
from jquery.
I did a query on GitHub for calls like ".attr('disabled', false)"
- and the same for other attributes - to see their popularity. This is not ideal - it only counts one type of quotes, it may not catch some formatting styles but it seems to correlate well with overall popularity. Here are the results with links:
disabled
: 78.1k files -".attr('disabled', false)"
checked
: 29.6k files -".attr('checked', false)"
readonly
: 4.7k files -".attr('readonly', false)"
selected
: 2k files -".attr('selected', false)"
required
: 1.7k files -".attr('required', false)"
hidden
: 952 files -".attr('hidden', false)"
open
: 514 files -".attr('open', false)"
autofocus
: 169 files -".attr('autofocus', false)"
multiple
: 145 files -".attr('multiple', false)"
Searches for all the other attributes generated less than 50 results.
controls
: 48 files -".attr('controls', false)"
loop
: 26 files -".attr('loop', false)"
autoplay
: 12 files -".attr('autoplay', false)"
async
: 1 file -".attr('async', false)"
defer
: 1 file -".attr('defer', false)"
ismap
: 0 files -".attr('ismap', false)"
scoped
: 0 files -".attr('scoped', false)"
I was surprised to see so few uses of the selected
setter. Based on the above and on the fact that generalizing the false
setter to mean attribute removal could break currently working code which depends on false
being stringified to "false"
, I propose to:
- Remove the boolean attribute getter completely - always return the attribute value instead of its name
- Remove the boolean attribute setter for all attributes with two exceptions:
disabled
&checked
- For
disabled
&checked
, limit the setter hook to remove for thefalse
value but remove the value normalization - set the value the user provided instead of the attribute name.
Of course, that is a breaking change; the few most common breakages:
- The getter may return a different value than in 3.x. If the code compares it directly to the attribute name, it will break.
- Even if strict comparison is not used, code may check for the value truthiness. If the setter was used with an empty string, the getter would return a falsy value.
We can add Migrate warnings for both cases.
Thoughts?
from jquery.
Given that any change is breaking for some cases (albeit possibly only hypothetical) and that the current behavior is wrong and will become more wrong over time as HTML expand more currently-boolean attributes to include other values, I am of the opinion that we should remove special treatment for any boolean attribute, generalizing the .attr(name, false)
setter to remove any attribute (which is both convenient behavior and important for existing code) and otherwise reflecting the DOM as-is. It would be unnecessarily confusing and inconsistent to privilege only disabled
and checked
.
from jquery.
I am of the opinion that we should remove special treatment for any boolean attribute, generalizing the .attr(name, false) setter to remove any attribute (which is both convenient behavior and important for existing code) and otherwise reflecting the DOM as-is.
I continue to be worried about the same as what I mentioned at one of our meetings - there are attributes with a valid "false"
value and lots of code depends on false
getting stringified to that value instead of causing the attribute to be deleted. This seems to especially apply to ARIA attributes, see e.g. the search for ".attr('aria-hidden', false)"
or ".attr('aria-checked', false)"
. It's also not just ARIA - the HTML spec mentions a few others in its non-normative Attributes table: contenteditable
, enctype
, spellcheck
, writingsuggestions
. I suspect code setting data-*
attributes may also depend on false
stringification. What if more attributes start treating "false"
as a valid value?
There's prior art for us special casing some inputs due to backwards compat even if we preferred to drop the code altogether; the logic when to auto-append px
to numeric values in .css()
is a good example:
Lines 1 to 33 in f80e78e
from jquery.
I thought about my original proposal and I think if we want to special-case, we should include more attributes, though, perhaps all with >50 search results above.
Our unit tests also tell a story - if we special cased not just false
to mean attribute removal but also true
for the value to replicate the attribute name, almost all our existing tests are passing.
Depending on how much we want to play safe, we could even keep a version of the getter that converts an empty string to the attribute name and returns the other values unchanged. That would make the HTML like <input checked>
and the check if ( $( input ).attr( "checked" ) ) { /* ... */ }
still work, avoiding the issue with an empty string being falsy. This pattern is, unfortunately, pretty popular; see the search for ".attr('checked')) {"
.
It would be hard to warn against this in Migrate as we can only patch the getter there, we cannot see it's being used as a truthy check.
from jquery.
I submitted #5451 implementing the conservative approach I mentioned above. We can make it less conservative be removing one or two parts from it. Let's discuss this today.
We can also go with Richard's solution of generalizing false
- but we need to assess the breaking change from removing stringification to "false"
for attributes where this is a valid value.
from jquery.
At the meeting, we decided to:
- Remove any special boolean attributes treatment
- Make the
false
value trigger attribute removal for all non-ARIA attributes, stringify it to"false"
for ARIA attributes
PR #5452 implements this proposal.
from jquery.
Related Issues (20)
- Cannot read properties of null (reading 'compareDocumentPosition') HOT 3
- Invalid links in blog article HOT 2
- The jquery.factory.js bundle is missing in the npm package in the 4.0.0-beta release HOT 2
- `require( "jquery" )` returns a module object when used with Webpack & jQuery 4.0.0-beta HOT 24
- v4 beta : mottie/tablesorter plugin fails with sort() and trim() missing HOT 1
- Jquery-UI getting Error With jQuery jQuery 4.0.0 BETA! HOT 4
- jQuery.get() 4.0 backward compatibility issue HOT 3
- Permissions policy violation due to unload event HOT 1
- Avoiding JQuery version disclosure on Angular's Script.JS HOT 1
- Scripts in dynamically set html always asynchronously loaded HOT 3
- jQuery 3.7.1 is still making wrong calculation of dimensions in Firefox. HOT 1
- Memory Leak: OriginAnchor HOT 6
- Memory Leak: boxSizingReliable HOT 4
- Triggering after an `alert()` in an event handler results in a JS error HOT 3
- The strange behavior generated by the append method HOT 1
- Avoid counting scroll twice in offset
- jQuery Migrate 3.4.0 - elem.focus() is not working HOT 3
- Issue or behaviour??? - 2.2.3 to 3.6.0 - active element changed on focus. HOT 2
- Issue using JQuery 3.7.1 and CSP HOT 2
- Jquery Vite installation doesnt work. HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from jquery.