Remove mystical incantations related to selectedIndex
See original GitHub issueDescription
This line is an example of programming by mystical incantation:
// Accessing this property makes selected-by-default
// options in Safari work properly
if ( elem.parentNode ) {
elem.parentNode.selectedIndex;
}
And there is at least one more just like it. Logically, the expression is a no-op. The comment indicates that somebody once saw it cause some side effect in an unspecified version of Safari.
For this reason, no lint will pass such a line. This comment confirms that our lint was forced to ignore the transgression.
// eslint rule "no-unused-expressions" is disabled for this code
If a fuse blows, you don’t put tinfoil between the contacts; it’s trying to tell you that something is wrong.
Furthermore, what makes us think that the parent of an OPTION
will be a SELECT
? Could be an OPTGROUP
.
As this issue has the potential to foul up form input, it should be given a high priority.
I’ll leave the solution to this one as an exercise for the moment. A solution was given to Resig several years ago and discussed in the old jQuery forum, as well as on Usenet. He mentioned something about not wanting to add an extra line and confirmed that he couldn’t find a browser that “proved” it didn’t work (i.e. show me where it fails). Hint: the no-op line has the answer and discards it. 😉
Link to test case
No test case. Not known for sure where or when it might fail. Do know that SELECT
elements without at least one OPTION
containing a SELECTED
attribute are vulnerable (as that creates an implicitly selected OPTION
).
Likely not an issue once the page is loaded, but without reviewing the DOM standards, can’t say for sure when browsers are required to set the selected
property to reflect an implicit selection. Instead of worrying about that (or testing), let’s just fix the logic.
PS. There is an attempt at a feature test that sets a flag that isn’t checked in relation to the above line, but it is checked in other areas of the code with similar lines:
var input = document.createElement( "input" ),
select = document.createElement( "select" ),
opt = select.appendChild( document.createElement( "option" ) );
...
// Support: IE <=11 only
// Must access selectedIndex to make default options select
support.optSelected = opt.selected;
One problem with that test is that it is testing a disembodied SELECT
and there’s certainly no guarantee that it will pass based on any standard that I know of (again, would have to consult the specifications). So false positives for this “problem” will likely occur, adding additional no-op execution for no reason at all. I know that jQuery is supposed to work with document fragments, but the SELECT
tested is without even that.
Another problem is it doesn’t test the assumed solution to see if it improves the situation, only that there may be a problem. Again, this will result in no-op execution without any reason to expect it will do anything useful.
A third problem is that the name of the flag (optSelected
) is not very descriptive of what it is supposed to mean. If it wasn’t tacked on to this support
object, we could make the name as long as we want as the minification process would reduce it. Regardless, saving a few bytes at the expense of clarity is a bad trade (not to mention that HTTP compression will likely end up saving the bytes anyway).
If we just fix the logic for the half dozen related lines then we don’t need this test at all. And BTW, what does “Support: IE <= 11 only” imply? See similar comments throughout and they don’t make a lot of sense to me (e.g. the original hack in this case was for some unspecified Safari version).
Issue Analytics
- State:
- Created 7 years ago
- Comments:10 (4 by maintainers)
It is what i meant and this is still not a sizzle repo. Sizzle and jquery are different projects, these differences are important, in this case this is important because we are planning to remove sizzle dep entirely.
You should start from that, but with the test-case on jsbin/jsfiddle that’s what others were trying to tell you.
And that’s what you should do in pull requests with new tests and without falling old tests.
And that’s what should be avoided. Since important information tend to get lost if you supply it with philosophy, irrelevant stories and etc.
See more on https://contribute.jquery.org/
That’s a ticket I definitely planned to create (dump Sizzle). That will eliminate the obvious problem I raised about them not being in sync. A bit late of course, but good that we are finally dumping that thing. And it that’s what you meant, why didn’t you just say that? Last thing we need here are riddles.
https://gist.github.com/david-mark/4ba4094ad7626227530eb98322aa33eb
Also of importance are all of the jQuery builds out there on the Web with incorrect code in them. So rather than brush off an obvious bug on a technicality, would suggest discussing how it is to be fixed across the three major versions (regardless of what repo the code originally comes from). Then we can worry about removing Sizzle, which I doubt is going to happen any time soon (and obviously never for the 1.x and 2.x versions).
That’s not what the others were saying. They were saying they really didn’t think it was a good idea to remove the hack. And they closed the ticket before understanding that I wasn’t suggesting that at all. For about the tenth time (with a new audience), I was implying that the logic needed to be replaced with something that made more sense.
You (and they) need to understand that the lack of a failing test doesn’t imply that the code makes sense (or that it won’t fail in the future). Browser scripting involves analysis and anticipation, not just reviewing test results in “current” browsers.
There’s no need for any new test cases for this as no behavior change is suggested. The original unit tests will confirm if used in browsers that actually have the quirk. End of story.
The ticket was closed because nobody seemed to understand the issue (thought I was saying to just remove the hack). Once it is closed, nobody is going to work on it (including me). No pull requests, nothing. Get it? 😃
What should be avoided? You appear to have quoted the wrong bit for that response.
I should have avoided discussing the issue with Resig several years back? That’s definitely important here as many of the “arguments” mention that I should go back and review the history of this issue (because they confusedly thought I was suggesting removing the hack without any replacement). And as mentioned repeatedly (and as you can see below), the answers were right where I pointed; instead of telling me to go back, would have been better to follow my lead and review the original issue and proposed solution. I already knew what they were as I posted them.
Or perhaps you mean I should have avoided posting the answer here after everyone else else refused to go back and look at the history I mentioned? Doesn’t really matter now as the ticket is closed.
For those who want to learn something from all this, here’s the history:
https://groups.google.com/forum/#!topic/jquery-dev/uu9ekb1xQDM[1-25]
That thread from 2009 starts off about
attr
and then turns to theSELECT
issue in this post from Matt Kruse.https://groups.google.com/d/msg/jquery-dev/uu9ekb1xQDM/fFM_6VTvRS4J
Note that Matt states quite clearly at the start of this thread that he’s relaying suggestions from me. That’s why I kept telling you that you were wasting time telling me to go back and read the history. In other words, of course I know what I’m doing. I wrote this book. 😃
Resig answers a few posts later:
Later Matt and Resig discussed a half-baked “fix” for the issue:
https://groups.google.com/forum/#!topic/jquery-dev/_mWIcai_8gg
…which is the very hack that we are discussing here now, seven years later. So, as mentioned repeatedly, there are no new test cases needed. Even @dmethvin mentioned that he had tried to remove (not replace) the hack and got unit test errors. Did I mention that no new test cases are needed? 😃
There are tickets referenced as well:
But note that Resig only took about half of my suggestions, rejecting the one I mentioned at the very start in this ticket, which is to replace the hack with logic that makes sense. The code is right there in the first post and it is almost exactly what I suggested above. Comes after the paragraph where Matt starts out:
That would be me and whoever else was in the related CLJ discussion. Yes, that CLJ. The group Resig not only refused to read, but refused to hear about at times, insisting nobody could mention any suggested solutions that originated from that Usenet group. That’s one reason that obvious junk code remains in the jQuery to this day.
In addition to Resig, who else is present in that first thread? None other than @dmethvin. Yes, that @dmethvin. The guy who single-handedly stalled this ticket until it was closed, insisting that I go back and find the history, so that I would not be confused about what that code was doing in there. 😃
https://groups.google.com/d/msg/jquery-dev/uu9ekb1xQDM/3_8dDMBCzC0J
As that was back in 2009 and it would be roughly another three years until the main subject of that thread (
attr
) was (ahem) fixed. Well, attempted and then reverted and then… we’ll never know as I’m not even getting into any more of this junk in 2017.But my point is that you can learn from the opening exchange between Kruse and Resig. Matt opens by recounting numerous issues with
attr
from one of my code reviews. You know, the ones Resig never read (and warned others to avoid). Matt provided the links to both the review and my old “A is for Attributes” primer. Resig responded much the way others have responded to this ticket.https://groups.google.com/d/msg/jquery-dev/uu9ekb1xQDM/Y5HfzUFlU-gJ
Three of his first four sentences were:
See more here: https://github.com/jquery/jquery/issues/3448