In core JS files, every time .parents()
is used .closest()
is what was meant.
.closest()
Begins with the current element
Travels up the DOM tree until it finds a match for the supplied selector
The returned jQuery object contains zero or one element
.parents()
Begins with the parent element
Travels up the DOM tree to the document's root element, adding each ancestor element to a temporary collection; it then filters that collection based on a selector if one is supplied
The returned jQuery object contains zero, one, or multiple elements
The js present in core never use multiple elements and always add a selector to limit results to 1 element. It's used with either :first
, .get(0)
, .eq(0)
or parents('tr')[0]
and sometimes it just hopes there is no nested structures (tableselect/tabledrag) #1319420: multiple execution of tableselect.js with nested tables.
The following patch replace all occurrences of .parents()
to .closest()
, in the very deep HTML tree Drupal usually outputs that could mean some pretty serious performance improvement. I checked every replacement by hand, it's all still working :)
Along the way I fixed a bug in shortcut.admin.js
where "New set" wouldn't be checked when focusing the text input.
filter.js
could be less complicated as the change event bubbles up, it can be catched by .filter-wrapper
directly.
Comment | File | Size | Author |
---|---|---|---|
#28 | core-js-parents-to-closest-backport-1400310-28.patch | 9.85 KB | m.stenta |
#24 | core-js-parents-to-closest-backport-1400310-24.patch | 9.89 KB | nod_ |
#13 | drupal8.closest-revert.13.patch | 9.93 KB | sun |
#8 | core-js-parents-to-closest-backport-1400310-8.patch | 9.89 KB | nod_ |
#8 | core-js-parents-to-closest-1400310-8-D8.patch | 659 bytes | nod_ |
Comments
Comment #1
nod_woops, forgot this.
Comment #2
nod_It's too late, sorry about this.
Comment #3
dawehnerOh that's a nice feature os jquery.
Trying out d8 had the behavior that the ui didn't automatically switched to the new radio button.
The new patch fixed this
This code looks quite unspecific, as there could be other forms which has new somewhere in the block but that's outside of scope of this issue.
-22 days to next Drupal core point release.
Comment #4
dawehnerUpdate status.
Comment #5
Dries CreditAttribution: Dries commentedThis looks like a nice clean-up that can improve performance and fix bugs. Committed to 8.x.
We should backport this to Drupal 7.
Comment #6
nod_Was not tested as well as D8 patch but everything looks in order.
Comment #7
dawehnerThe patch is the same as for 8.x so i just test the functionality.
As written in irc this patch breaks the views ui. You have to click twice on every link to get it working, I'm sorry for that :(
Comment #8
nod_My apologies, I messed up the only relevant use of
.parents()
.This applies to D8 too, the following patches fixes the issue for D8 and the patch is rerolled for D7 including the fix (more like not including my "fix" :p).
Sorry about that.
Comment #9
dawehnerThis version works in the ui.
Let's get first the bugfix into d8.
Comment #10
Dries CreditAttribution: Dries commentedCommitted the bugfix core-js-parents-to-closest-1400310-8-D8.patch (659 bytes) to 8.x. Back to Drupal 7.
Comment #11
sunWTF? Seriously, what's going on here?
Change the JS of plenty modules without a single confirmation that the expected functionality still works in all browsers...?
Comment #12
sunThat said, the changes converting
.parents('*:first')
into.closest('*')
seem to be correct.I did not, however, test them manually.
toggleClass() was intentionally not used here, because it is unreliable in bulk operations.
When clicking the check-all checkbox, a checkbox (or checkbox row) is factually unchecked if it is already checked.
This selects something completely different.
As noted in #3 it seems to fix an actual, separate bug. So it's quite unfortunate to have that fix squeezed in here. Did you search for existing issues?
Comment #13
sunLacking proper reviews and any proper testing, here's a total revert of the cumulative patches.
EDIT: That said, using a native git revert would be better, as it provides more context and magic:
Comment #15
nod_Wow I certainly wasn't trying to get anyone angry.
I did search for existing issues regarding #3, no luck. As it's not a change in js present in /misc and it's used only for shortcut admin I don't see the issue of selecting a different element, which is needed because it's not possible to fix this with what the former selector was giving. parents was used incorrectly here too.
I checked that elements selected by the new selectors were exactly the same as before for every replacement. If it's different from a browser to another it's a bug in jQuery.
Regarding the toggleClass I didn't know about the reliability issue (never had an issue with it), do you have more info? I'm interested to know about that and I couldn't find a ticket talking about this in jQuery's bug tracker. And I can't see the issue you're raising about checkbox rows getting unchecked (or rather unselected), works for me.
As for the mess in
ajax.js
that broke views UI, it was me trying to be too smart.(edit) oh and what's happening with js testing? should I go with qunit module if I want to write tests for my patches? Because this is not going to end well if manual testing is needed for all js refactors.
Comment #16
sunI overlooked that the second parameter to .toggleClass() was used here, which is a Boolean to enforce either .addClass() or .removeClass(), instead of the regular .toggleClass() behavior.
Yes, manual testing is required for all JS patches. Additionally, some JS is written in a way to allow contrib modules to do advanced things, so some API changes may need to be confirmed by testing whether more complex contrib modules still work or can be adapted.
Comment #17
nod_I figured testing was required, just wanted to know if writing core tests for the qunit module could be considered testing and make our life much easier. Workflow ending up like, here is my patch, you can find qunit tests there run that on your browser check it's enough testing and mark need work or rtbc. I wasn't hopping for test bot integration.
Dries tagged it as needing backport to 7.x, what's the final decision about that ?
Comment #18
sunWhat essentially happened here is that the D8 patch is now tested by the crowd of core developers. Since D8 cannot be used for production sites, it's unlikely that anyone happens to "implicitly" test all of these changes soonish.
Someone needs to have a close look at the queue of new issues filed for D8 core to make sure that this change did not break something.
A backport to D7 requires full manual testing.
Comment #19
nod_It's all in the hands of a Good Samaritan then.
Comment #20
nod_Comment #21
nod_If people want to help review, patch for D7 is at #8.
Comment #22
Niklas Fiekas CreditAttribution: Niklas Fiekas commentedHit the wrong patch, or does it need a reroll?
Comment #23
nod_Yeah probably, quite a few changes has been made on js files.
Comment #24
nod_Should work now :)
Comment #25
Niklas Fiekas CreditAttribution: Niklas Fiekas commentedYep. Looks like everything is still working.
Comment #26
webchickCan we be clear on what exactly was tested here, and in what browsers?
Comment #27
nod_The change is browser agnostic, and I've using the patch on my dev D7 and didn't run into any issue with tabledrag, file upload and the rest of it.
Went to each page the files were used and it still works. But since I made the patch…
Comment #28
m.stentaThe patch in #24 didn't apply against the latest HEAD (due to commit 0025dcb), so I rerolled it.
Comment #29
m.stentaTested the following:
I went through each change and tested them all manually. These are the results. Note that there were a few specific pieces I did not test (see note at bottom of this comment).
Attaching machine-name form element JS bahavior
Pages tested:
/admin/structure/taxonomy/tags/edit (vocabulary machine name)
/admin/structure/types/manage/article (content type machine name)
Results:
-Successfully attaches the JS behavior to the machin-name form element, causing it to be collapsed into something like "Machine name: article [Edit]" next to the "Name" field, and clicking "[Edit]" expands the machine-name field as expected.
Hiding "weight" columns in draggable tables
Pages tested:
/admin/structure/taxonomy/tags (tags vocab with some test terms)
Results:
-Successfully hides the "weight" column.
"Select all" checkbox behvaior in tableselect.js
Pages tested:
/admin/content
Results:
-Successfully selects all checkboxes when the "Select All" checkbox is checked.
-Successfully checks the "Select All" checkbox when all checkboxes are manually checked.
-Successfully unchecks the "Select All" checkbox when all of the checkboxes are checked, and then one or more is manually unchecked.
Blocks region select list
Pages tested:
/admin/structure/block
Results:
-Successfully moves a block from one region to another when a different region is selected in the block's Region select list.
"Add new field" field-type select list
Pages tested:
/admin/structure/types/manage/article/fields
Results:
-Successfully updates the "Widget" select list options when the value of the "Field type" select list changes
"Add existing field" name select list
Pages tested:
/admin/structure/types/manage/page/fields
Results:
-Successfully updates the "Widget" select list options, and fills in the "Label" text field when the "Select an existing field" select list is changed.
"Format" select list in Fields "Manage Display"
Pages tested:
/admin/structure/types/manage/article/display
Results:
-Successfully changes the region that a field is in when the "Format" select list is set to "".
File field extension validation
Pages tested:
/node/1/edit
Results:
-Successfully displays validation error message above file field when a file with the wrong extension is selected.
Input filter guidelines
Pages tested:
/node/2/edit
Results:
-Successfully swaps out the input filter guidelines UL list when a different one is selected from the "Text format" select list.
"Cool table collapsing on the testing overview page"
Pages tested:
/admin/config/development/testing
Results:
-Successfully collapses and expands the test groups in the list of tests.
Specific parts I did NOT test:
I wasn't sure where to go to test the following pieces, or they involved more in-depth environment setup:
Line 757 of misc/tabledrag.js:
Line 889 of misc/tabledrag.js:
Line 98 of modules/file/file.js:
Line 121 of modules/file/file.js:
Line 135 of modules/file/file.js:
Line 109 of modules/shortcut/shortcut.admin.js:
However, I think it's safe to say that they will work, because the changes that have been made to them are syntactically the same as all the changes that I DID test above.
Comment #30
nod_Oh my god, you're awesome. Thank you so much for testing all of this.
the bits and pieces you did not test in tabledrag were implicitly tested since it's used by other pieces of code. The file js was tested if you sucessfully uploaded a big file and the progressbar showed up. for the newSet, if on the shortcut module by clicking on "Other" the textfield got focus it would be a successful test.
If we ever run into each other, drinks are on me!
Comment #31
m.stentaJust talked with xjm, and she said to mark this back to "Needs Review" until it can get tested in all supported browsers for 7.x (http://drupal.org/node/61509).
Since this is already committed to 8.x, that just means in needs to work in IE 6 and 7 (support for those two is dropped in 8.x).
Edit: FYI ... I tested it in Chrome originally.
Comment #32
nod_the change is browser agnostic, if there is an issue it's a jQuery/Sizzle bug.
Thanks again for taking the time to do all this.
Comment #33
droplet CreditAttribution: droplet commentedI agreed with @nod_
Comment #34
m.stentaChanging this back to RTBC, after further discussion with xjm. Since the JS maintainer is cool with it, it should be good to go. I'll leave it up to the committer to decide whether it needs manual IE6 testing, or if we can assume it's good to go based on jQuery's browser agnosticism.
To-the-committer-whom-it-may-concern: see comment #29 for my full testing (done in Chrome) and #32 for nod_'s go-ahead. Also note this is already committed to 8.x, so it's just a matter of IE6 compatibility, which as nod_ said, is up to jQuery and should work.
Comment #35
tim.plunkettConfirming RTBC, in case there was any worry about the reroller RTBCing.
Comment #37
webchickWow, that's some EPIC manual testing there, m.stenta! Thank you so much!
I agree with nod_ that since we're testing a jQuery function change, testing in one browser should be sufficient here.
Committed and pushed to 7.x. Thanks!!
Comment #38
nod_Awesome! thanks everyone for reviewing the patch!